21 game

You are encouraged to solve this task according to the task description, using any language you may know.
21 is a two player game, the game is played by choosing
a number (1, 2, or 3) to be added to the running total.

The game is won by the player whose chosen number causes the running total
to reach exactly 21.

The running total starts at zero.
One player will be the computer.

Players alternate supplying a number to be added to the running total.



Task

Write a computer program that will:

 do the prompting (or provide a button menu), 
 check for errors and display appropriate error messages, 
 do the additions (add a chosen number to the running total), 
 display the running total, 
 provide a mechanism for the player to quit/exit/halt/stop/close the program,
 issue a notification when there is a winner, and
 determine who goes first (maybe a random or user choice, or can be specified when the game begins). 


 
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program game21_64.s   */ 
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
.equ HITTOTAL,   21
.equ BUFFERSIZE, 10
 
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessRules:         .ascii "21 Game\n"
                    .ascii "21 is a two player game, the game is played by choosing a number \n"
                    .ascii "(1, 2, or 3) to be added to the running total. The game is won by\n"
                    .ascii "the player whose chosen number causes the running total to reach \n"
                    .asciz "exactly 21. The running total starts at zero.\n\n\n"
 
szMessHumanChoice:  .asciz "Enter your choice (1,2, 3 or type (q)uit to exit): "
szMessErrChoise:    .asciz "invalid choice.\n  "
szMessHumanBegin:   .asciz "The first move is human move.\n"
szMessPiBegin:      .asciz "The first move is Raspberry pi. \n"
szMessHumanWon:     .asciz "You won. \n"
szMessHumanLost:    .asciz "You lost. \n"
szMessTotal:        .asciz "The running total is @ \n"
szMessPiChoice:     .asciz "Raspberry choice is  @ \n" 
szMessNewGame:      .asciz "New game (y/n) ? \n"
szCarriageReturn:   .asciz "\n"
.align 4
qGraine:  .quad 123456
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:        .skip 24
sBuffer:          .skip BUFFERSIZE
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                 // entry of program 
 
    ldr x0,qAdrszMessRules
    bl affichageMess
1:
    mov x10,#0                         // total = 0
    mov x0,#100
    bl genereraleas 
    cmp x0,#50
    blt 2f
    ldr x0,qAdrszMessHumanBegin        // human begin
    bl affichageMess
    b 4f
2:                                     // Rasp begin
    ldr x0,qAdrszMessPiBegin
    bl affichageMess
    mov x0,#1
3:                                    // rasp turn
    add x10,x10,x0
    ldr x1,qAdrsZoneConv
    bl conversion10                   // call decimal conversion
    ldr x0,qAdrszMessPiChoice
    ldr x1,qAdrsZoneConv              // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
    cmp x10,#HITTOTAL
    bne 4f
    ldr x0,qAdrszMessHumanLost
    bl affichageMess
    b 12f
4:                                    // display current total
    mov x0,x10
    ldr x1,qAdrsZoneConv
    bl conversion10                   // call decimal conversion
    ldr x0,qAdrszMessTotal
    ldr x1,qAdrsZoneConv              // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
 
5:                                    // human turn
    ldr x0,qAdrszMessHumanChoice
    bl affichageMess
    bl saisie
    cmp x0,#'q'                       // quit ?
    beq 100f
    cmp x0,#'Q'
    beq 100f
    cmp x0,#'1'
    add x9,x10,1
    csel x10,x9,x10,eq
    beq 6f
    cmp x0,#'2'
    add x9,x10,2
    csel x10,x9,x10,eq
    beq 6f
    cmp x0,#'3'
    add x9,x10,3
    csel x10,x9,x10,eq
    beq 6f
    ldr x0,qAdrszMessErrChoise
    bl affichageMess
    b 5b
6:
    cmp x10,#HITTOTAL                // total = maxi ?
    beq 11f                           // yes -> human won
    cmp x10,#5                       // else compute rasp number
    mov x9,5                         // compare total and optimun
7:
    cmp x10,x9
    ble 8f
    add x9,x9,4
    b 7b
8:
    sub x0,x9,x10                   // compute number rasp
9:                                  // control number rasp
    cmp x0,#0
    ble 10f
    cmp x0,#3
    ble 3b
10:                                  // if not ok, generate random number
    mov x0,#2
    bl genereraleas
    add x0,x0,#1
    b 3b                            // and loop
 
11:                                  // display human won
    ldr x0,qAdrszMessHumanWon
    bl affichageMess
12:                                 // display new game ?
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
    ldr x0,qAdrszMessNewGame
    bl affichageMess
    bl saisie
    cmp x0,#'y'
    beq 1b
    cmp x0,#'Y'
    beq 1b
 
100:                                  // standard end of the program 
    mov x0, #0                        // return code
    mov x8, #EXIT                     // request to exit program
    svc #0                            // perform the system call
 
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrszMessRules:          .quad szMessRules
qAdrszMessHumanBegin:     .quad szMessHumanBegin
qAdrszMessPiBegin:        .quad szMessPiBegin
qAdrszMessPiChoice:       .quad szMessPiChoice
qAdrszMessTotal:          .quad szMessTotal
qAdrszMessHumanChoice:    .quad szMessHumanChoice
qAdrszMessHumanLost:      .quad szMessHumanLost
qAdrszMessHumanWon:       .quad szMessHumanWon
qAdrszMessNewGame:        .quad szMessNewGame
qAdrszMessErrChoise:      .quad szMessErrChoise
qAdrsZoneConv:            .quad sZoneConv
/******************************************************************/
/*            string saisie                                       */ 
/******************************************************************/
/* x0 return the first character of human entry */
saisie:
    stp x1,lr,[sp,-16]!    // save  registers
    stp x2,x8,[sp,-16]!    // save  registers
    mov x0,#STDIN          // Linux input console
    ldr x1,qAdrsBuffer     // buffer address 
    mov x2,#BUFFERSIZE     // buffer size 
    mov x8,#READ           // request to read datas
    svc 0                  // call system
    ldr x1,qAdrsBuffer     // buffer address 
    ldrb w0,[x1]           // load first character
100:
    ldp x2,x8,[sp],16      // restaur  2 registers
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
 
qAdrsBuffer:         .quad sBuffer
/***************************************************/
/*   Generation random number                  */
/***************************************************/
/* x0 contains limit  */
genereraleas:
    stp x1,lr,[sp,-16]!        // save  registers
    stp x2,x3,[sp,-16]!        // save  registers
    stp x4,x5,[sp,-16]!        // save  registers
    ldr x4,qAdrqGraine
    ldr x2,[x4]
    ldr x3,qNbDep1
    mul x2,x3,x2
    ldr x3,qNbDep2
    add x2,x2,x3
    str x2,[x4]                // maj de la graine pour l appel suivant 
    cmp x0,#0
    beq 100f
    udiv x3,x2,x0
    msub x0,x3,x0,x2           // résult = remainder
 
100:                           // end function
    ldp x4,x5,[sp],16          // restaur  2 registers
    ldp x2,x3,[sp],16          // restaur  2 registers
    ldp x1,lr,[sp],16          // restaur  2 registers
    ret                        // return to address lr x30
/*****************************************************/
qAdrqGraine: .quad qGraine
qNbDep1:     .quad 0x0019660d
qNbDep2:     .quad 0x3c6ef35f
 
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 