石取りゲーム1

目次

Unknown programmer's programming note.

<2022-09-22 木>

1. プログラムの概要

ishi1 - 石取りゲームをプレイする

2. C

/*
 * 出典元「C言語による最新アルゴリズム事典」奥村晴彦著 - P6
 * インデントは変更してあります。
 * 他にも、メッセージや変数名や処理を変更している場合があります。
 */
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n, m, x, r, my_turn;

    printf("How many stones? ");
    scanf("%d", &n);

    printf("Max stones at one turn? ");
    scanf("%d", &m);

    if (n < 1 || m < 1)
    {
        fprintf(stderr, "Invalid game settings\n");
        return EXIT_FAILURE;
    }

    for (my_turn = 1; n != 0; my_turn ^= 1)
    {
        if (my_turn)
        {
            x = (n - 1) % (m + 1);
            if (x == 0)
            {
                x = 1;
            }
            if (x == 1)
            {
                printf("I take one stone.\n");
            }
            else
            {
                printf("I take %d stones.\n", x);
            }
        }
        else
        {
            do
            {
                printf("How many stones do you take? ");
                r = scanf("%d", &x);
                scanf("%*[^\n]");
            } while (r != 1 || x <= 0 || x > m || x > n);
        }

        n -= x;
        if (n == 1)
        {
            printf("There remains one stone.\n");
        }
        else
        {
            printf("There remain %d stones.\n", n);
        }
    }

    if (my_turn)
    {
        printf("You lose!\n");
    }
    else
    {
        printf("I lose!\n");
    }
}

3. Emacs Lisp

(defun ishi ()
  (let ((n (read-number "How many stones? "))
        (m (read-number "Max stones at one turn? "))
        (my-turn t)
        output-buffer)

    (when (or (< n 1) (< m 1))
      (error "Invalid game settings"))

    (setq output-buffer (get-buffer-create "*ishi*"))
    (switch-to-buffer-other-window output-buffer)
    (goto-char (point-max))
    (if (step-turn n m my-turn)
        (insert (format "I lose!\n"))
      (insert (format "You lose!\n")))
    ))

(defun step-turn (n m my-turn)
  (let ((x 0) n-next)
    (cond (my-turn
           (setq x (% (1- n) (1+ m)))
           (when (= x 0)
             (setq x 1))

           (if (= x 1)
               (insert (format "I take one stone.\n"))
             (insert (format "I take %d stones.\n" x))))

          (t
           (while (progn
                    (setq x (read-number "How many stones do you take? "))
                    (or (<= x 0) (> x m) (> x n))
                    ))
           ))

    (setq n-next (- n x))

    (if (= 1 n-next)
        (insert (format "There remains one stone.\n"))
      (insert (format "There remain %d stones.\n" n-next)))

    (if (<= n-next 0)
        my-turn
      (step-turn n-next m (not my-turn)))))

(ishi)

4. Bash

#!/bin/bash

read -p "How many stones? " n
read -p "Max stones at one turn? " m

if [ $n -lt 1 -o $m -lt 1 ]
then
    echo "Invalid game setting" 1>&2
    exit 1
fi

my_turn=0

function is_my_turn {
    return $(test $my_turn -eq 0)
}

while [ $n -gt 0 ]
do
    if is_my_turn
    then
        x=$(( ($n - 1) % (m + 1) ))
        if [ $x -eq 0 ]
        then
            $x=1
        fi

        if [ $x -eq 1 ]
        then
            echo "I take one stone."
        else
            echo "I take $x stones."
        fi
    else
        while
            read -p "How many stones do you take? " x
            [ $? -ne 0 -o $x -le 0 -o $x -gt m -o $x -gt $n ]
        do true; done
    fi

    n=$(( $n - $x ))

    if [ $n -eq 1 ]
    then
        echo "There remains one stone."
    else
        echo "There remain $n stones."
    fi

    if is_my_turn
    then
        my_turn=1
    else
        my_turn=0
    fi
done

if is_my_turn
then
    echo "Your lose!"
else
    echo "I lose!"
fi

5. Fish

#!/usr/bin/fish

read -P "How many stones? " n
read -P "Max stones at one turn? " m

if test $n -lt 1 -o $m -lt 1
    echo "Invalid game settings"
    exit 1
end

set my_turn 0

function is_my_turn
    return (test $my_turn -eq 0)
end

while test $n -ne 0
    if is_my_turn
        set x (math "($n - 1) % ($m + 1)")
        if test $x -eq 0
            set x 1
        end

        if test $x -eq 1
            echo "I take one stone."
        else
            echo "I take $x stones."
        end
    else
        set -l ok 1
        while test $ok -ne 0
            read -P "How many stones do you take? " x
            if test $status -ne 0
                return 1
            else if test $x -lt 1 -o $x -gt $m -o $x -gt $n
                set ok 1
            else
                set ok 0
            end
        end
    end

    set n (math $n - $x)

    if test $n -eq 1
        echo "There remains one stone."
    else
        echo "There remain $n stones."
    end

    if is_my_turn
        set my_turn 1
    else
        set my_turn 0
    end
end

if is_my_turn
    echo "You lose!"
else
    echo "I lose!"
end

著者: watercat

Created: 2022-09-24 土 02:24

Emacs 28.2 (Org mode 9.5.5)

Validate