Task: 21 game

C: 



#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


#if __STDC_VERSION__ >= 199901L || _MSC_VER >= 1800
#include <stdbool.h>
#else
#define bool int
#define true  1
#define false 0
#endif

#define GOAL               21
#define NUMBER_OF_PLAYERS   2
#define MIN_MOVE            1
#define MAX_MOVE            3
#define BUFFER_SIZE       256

#define _(STRING) STRING



static char DESCRIPTION[] = 
    "21 Game                                                          \n"
    "                                                                 \n"
    "21 is a two player game, the game is played by choosing a number \n"
    "(1, 2, or 3) to be added to the running total. The game is won by\n"
    "the player whose chosen number causes the running total to reach \n"
    "exactly 21. The running total starts at zero.                    \n\n";

static int total;


void update(char* player, int move)
{
    printf("%8s:  %d = %d + %d\n\n", player, total + move, total, move);
    total += move;
    if (total == GOAL)
        printf(_("The winner is %s.\n\n"), player);
}


int ai()
{

#if GOAL < 32 && MIN_MOVE == 1 && MAX_MOVE == 3
    static const int precomputed[] = { 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1,
        3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3 };
    update(_("ai"), precomputed[total]);
#elif MIN_MOVE == 1 && MAX_MOVE == 3
    static const int precomputed[] = { 1, 1, 3, 2};
    update(_("ai"), precomputed[total % (MAX_MOVE + 1)]);
#else
    int i;
    int move = 1;
    for (i = MIN_MOVE; i <= MAX_MOVE; i++)
        if ((total + i - 1) % (MAX_MOVE + 1) == 0)
            move = i;
    for (i = MIN_MOVE; i <= MAX_MOVE; i++)
        if (total + i == GOAL)
            move = i;
    update(_("ai"), move);
#endif
}


void human(void)
{
    char buffer[BUFFER_SIZE];
    int move;
 
    while ( printf(_("enter your move to play (or enter 0 to exit game): ")),
            fgets(buffer, BUFFER_SIZE, stdin), 
            sscanf(buffer, "%d", &move) != 1 ||
            (move && (move < MIN_MOVE || move > MAX_MOVE || total+move > GOAL)))
        puts(_("\nYour answer is not a valid choice.\n"));
    putchar('\n');
    if (!move) exit(EXIT_SUCCESS);
    update(_("human"), move);
}


int main(int argc, char* argv[])
{
    srand(time(NULL));
    puts(_(DESCRIPTION));
    while (true)
    {
        puts(_("\n---- NEW GAME ----\n"));
        puts(_("\nThe running total is currently zero.\n"));
        total = 0;

        if (rand() % NUMBER_OF_PLAYERS)
        {
            puts(_("The first move is AI move.\n"));
            ai();
        }
        else
            puts(_("The first move is human move.\n"));

        while (total < GOAL)
        {
            human();
            ai();
        }
    }
}











Ada: with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Game_21 is

   procedure Put (Item : String) is
   begin
      for Char of Item loop
         Ada.Text_IO.Put (Char);
         delay 0.010;
      end loop;
   end Put;

   procedure New_Line is
   begin
      Ada.Text_IO.New_Line;
   end New_Line;

   procedure Put_Line (Item : String) is
   begin
      Put (Item);
      New_Line;
   end Put_LIne;

   type Player_Kind is (Human, Computer);
   type Score_Type  is range 0 .. 21;
   subtype Amount_Range is Score_Type range 1 .. 3;

   package Amount_Generators is
     new Ada.Numerics.Discrete_Random (Amount_Range);

   Gen    : Amount_Generators.Generator;
   Total  : Score_Type := 0;
   Choice : Character;
   Player : Player_Kind;
   Amount : Amount_Range;
begin
   Amount_Generators.Reset (Gen);

   Put_Line ("

   Put ("Who is starting human or computer (h/c) ? ");
   Ada.Text_IO.Get_Immediate (Choice);
   New_Line;

   case Choice is
      when 'c' | 'C' =>  Player := Computer;
      when 'h' | 'H' =>  Player := Human;
      when others => return;
   end case;

   Play_Loop : loop
      New_Line;
      Put ("Runing total is "); Put (Total'Image); New_Line;
      New_Line;

      case Player is

         when Human =>
            Put_Line ("It is your turn !");
            Input_Loop : loop
               Put ("Enter choice 1 .. 3 (0 to end) : ");
               Ada.Text_IO.Get_Immediate (Choice);

               case Choice is
                  when '1' .. '3' =>
                     Amount := Amount_Range'Value ("" & Choice);
                     exit Input_Loop;

                  when '0' =>
                     exit Play_Loop;

                  when others =>
                     Put_Line ("Choice must be in 1 .. 3");
               end case;
            end loop Input_Loop;
            New_Line;

         when Computer =>
            delay 1.500;
            Amount := Amount_Generators.Random (Gen);
            Put ("Computer chooses: "); Put (Amount'Image); New_Line;
            delay 0.800;

      end case;

      New_Line;
      Amount := Score_Type'Min (Amount, Score_Type'Last - Total);
      Put ("  "); Put (Total'Image); Put (" + ");  Put (Amount'Image); Put (" = ");
      Total := Total + Amount;
      Put (Total'Image);
      New_Line;

      if Total = 21 then
         New_Line;
         Put ("... and we have a WINNER !!"); New_Line;
         delay 0.500;
         Put_Line ("   ... and the winner is ...");
         delay 1.000;
         Put_Line ("      " & Player'Image);
         exit;
      end if;

      Player := (case Player is
                 when Computer => Human,
                 when Human    => Computer);
   end loop Play_Loop;
end Game_21;