2048 code

2048 code DEFAULT
Task
2048
You are encouraged to solve this taskaccording to the task description, using any language you may know.
Task

Implement a 2D sliding block puzzle game where blocks with numbers are combined to add their values.

Rules of the game
  •   The rules are that on each turn the player must choose a direction   (up, down, left or right).
  •   All tiles move as far as possible in that direction, some move more than others.
  •   Two adjacent tiles (in that direction only) with matching numbers combine into one bearing the sum of those numbers.
  •   A move is valid when at least one tile can be moved,   if only by combination.
  •   A new tile with the value of   2   is spawned at the end of each turn at a randomly chosen empty square   (if there is one).
  •   Adding a new tile on a blank space.   Most of the time,   a new   2   is to be added,   and occasionally   (10% of the time),   a   4.
  •   To win,   the player must create a tile with the number   2048.
  •   The player loses if no valid moves are possible.


The name comes from the popular open-source implementation of this game mechanic, 2048.

Requirements
  •   "Non-greedy" movement.  
      The tiles that were created by combining other tiles should not be combined again during the same turn (move).  
      That is to say,   that moving the tile row of:
[2][2][2][2]
to the right should result in:
......[4][4]
and not:
.........[8]
  •   "Move direction priority".  
      If more than one variant of combining is possible,   move direction shall indicate which combination will take effect.
      For example, moving the tile row of:
...[2][2][2]
to the right should result in:
......[2][4]
and not:
......[4][2]
  •   Check for valid moves.   The player shouldn't be able to skip their turn by trying a move that doesn't change the board.
  •   Check for a  win condition.
  •   Check for a lose condition.

AArch64 Assembly[edit]

Works with: as version Raspberry Pi 3B version Buster 64 bits

 
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program 2048_64.s */
 
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ SIZE, 4
.equ TOTAL, 2048
.equ BUFFERSIZE, 80
 
.equ KEYSIZE, 8
.equ IOCTL, 0x1D // Linux syscall
.equ SIGACTION, 0x86 // Linux syscall
.equ SYSPOLL, 0x16 // Linux syscall
.equ CREATPOLL, 0x14 // Linux syscall
.equ CTLPOLL, 0x15 // Linux syscall
 
.equ TCGETS, 0x5401
.equ TCSETS, 0x5402
.equ ICANON, 2
.equ ECHO, 10
.equ POLLIN, 1
.equ EPOLL_CTL_ADD, 1
 
.equ SIGINT, 2 // Issued if the user sends an interrupt signal (Ctrl + C)
.equ SIGQUIT, 3 // Issued if the user sends a quit signal (Ctrl + D)
.equ SIGTERM, 15 // Software termination signal (sent by kill by default)
.equ SIGTTOU, 22
 
/*******************************************/
/* Structures */
/********************************************/
/* structure termios see doc linux*/
.struct 0
term_c_iflag: // input modes
.struct term_c_iflag + 4
term_c_oflag: // output modes
.struct term_c_oflag + 4
term_c_cflag: // control modes
.struct term_c_cflag + 4
term_c_lflag: // local modes
.struct term_c_lflag + 4
term_c_cc: // special characters
.struct term_c_cc + 40 // see length if necessary
term_fin:
 
/* structure sigaction see doc linux */
.struct 0
sa_handler:
.struct sa_handler + 8
sa_mask:
.struct sa_mask + 8
sa_flags:
.struct sa_flags + 8
sa_sigaction:
.struct sa_sigaction + 8
sa_fin:
 
/* structure poll see doc linux */
.struct 0
poll_event: // events mask
.struct poll_event + 8
poll_fd: // events returned
.struct poll_fd + 8
poll_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessOK: .asciz "Bravo !! You win. \n"
szMessNotOK: .asciz "You lost !! \n"
szMessNewGame: .asciz "New game (y/n) ? \n"
szMessErreur: .asciz "Error detected.\n"
szMessErrInitTerm: .asciz "Error terminal init.\n"
szMessErrInitPoll: .asciz "Error poll init.\n"
szMessErreurKey: .asciz "Error read key.\n"
szMessErr: .asciz "Error code hexa : @ décimal : @ \n"
szCarriageReturn: .asciz "\n"
szMess0: .asciz " "
szMess2: .asciz " 2 "
szMess4: .asciz " 4 "
szMess8: .asciz " 8 "
szMess16: .asciz " 16 "
szMess32: .asciz " 32 "
szMess64: .asciz " 64 "
szMess128: .asciz " 128 "
szMess256: .asciz " 256 "
szMess512: .asciz " 512 "
szMess1024: .asciz " 1024 "
szMess2048: .asciz " 2048 "
szCleax1: .byte 0x1B
.byte 'c' // other console clear
.byte 0
 
szLineH: .asciz "-----------------------------\n"
szLineV: .asciz "|"
szLineVT: .asciz "| | | | |\n"
.align 4
qGraine: .quad 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
qTbCase: .skip 8 * SIZE * SIZE
qEnd: .skip 8 // 0 loop 1 = end loop
qTouche: .skip KEYSIZE // value key pressed
stOldtio: .skip term_fin // old terminal state
stCurtio: .skip term_fin // current terminal state
stSigAction: .skip sa_fin // area signal structure
stSigAction1: .skip sa_fin
stSigAction2: .skip sa_fin
stSigAction3: .skip sa_fin
stPoll1: .skip poll_fin // area poll structure
stPoll2: .skip poll_fin
stevents: .skip 16
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
mov x0,#0
bl initTerm // terminal init
cmp x0,0 // error ?
blt 100f
bl initPoll // epoll instance init
cmp x0,0
blt 99f
mov x22,x0 // save epfd
1: // begin game loop
ldr x0,qAdrszCleax1
bl affichageMess
bl razTable
2:
bl addDigit
cmp x0,#-1
beq 5f // end game
bl displayGame
3:
mov x0,x22
bl waitKey
cmp x0,0
beq 3b
bl readKey
cmp x0,#-1
beq 99f // error
bl keyMove
cmp x0,#0
beq 3b // no change -> loop
cmp x0,#2 // last addition = 2048 ?
beq 4f
cmp x0,#-1 // quit ?
bne 2b // loop
 
b 10f
4: // last addition = 2048
ldr x0,qAdrszMessOK
bl affichageMess
b 10f
5: // display message no solution
ldr x0,qAdrszMessNotOK
bl affichageMess
 
10: // display new game ?
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszMessNewGame
bl affichageMess
11:
mov x0,x22
bl waitKey
cmp x0,0
beq 11b
bl readKey
ldr x0,qAdrqTouche
ldrb w0,[x0]
cmp w0,#'y'
beq 1b
cmp w0,#'Y'
beq 1b
99:
bl restauTerm // terminal restaur
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
qAdrszMessNotOK: .quad szMessNotOK
qAdrszMessOK: .quad szMessOK
qAdrszMessNewGame: .quad szMessNewGame
qAdrsZoneConv: .quad sZoneConv
qAdrszCleax1: .quad szCleax1
qAdrszMessErrInitTerm: .quad szMessErrInitTerm
qAdrszMessErrInitPoll: .quad szMessErrInitPoll
qAdrszMessErreurKey: .quad szMessErreurKey
qAdrstOldtio: .quad stOldtio
qAdrstCurtio: .quad stCurtio
qAdrstSigAction: .quad stSigAction
qAdrstSigAction1: .quad stSigAction1
qAdrSIG_IGN: .quad 1
qAdrqEnd: .quad qEnd
qAdrqTouche: .quad qTouche
qAdrstevents: .quad stevents
/******************************************************************/
/* raz table cases */
/******************************************************************/
razTable:
stp x0,lr,[sp,-16]! // save registres
stp x1,x2,[sp,-16]! // save registres
ldr x1,qAdrqTbCase
mov x2,#0
1:
str xzr,[x1,x2,lsl #3]
add x2,x2,#1
cmp x2,#SIZE * SIZE
blt 1b
100:
ldp x1,x2,[sp],16 // restaur des 2 registres
ldp x0,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* key move */
/******************************************************************/
/* x0 contains key value */
keyMove:
stp x1,lr,[sp,-16]! // save registres
lsr x0,x0,#16
cmp x0,#0x42 // down arrow
bne 1f
bl moveDown
b 100f
1:
cmp x0,#0x41 // high arrow
bne 2f
bl moveUp
b 100f
2:
cmp x0,#0x43 // right arrow
bne 3f
bl moveRight
b 100f
3:
cmp x0,#0x44 // left arrow
bne 4f
bl moveLeft
b 100f
4:
ldr x0,qAdrqTouche
ldrb w0,[x0]
cmp w0,#'q' // quit game
bne 5f
mov x0,#-1
b 100f
5:
cmp w0,#'Q' // quit game
bne 100f
mov x0,#-1
b 100f
 
100:
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* move left */
/******************************************************************/
/* x0 return -1 if ok */
moveLeft:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
ldr x1,qAdrqTbCase
mov x0,#0 // top move Ok
mov x2,#0 // line indice
1:
mov x6,#0 // counter empty case
mov x7,#0 // first digit
mov x10,#0 // last digit to add
mov x3,#0 // column indice
2:
lsl x5,x2,#2 // change this if size <> 4
add x5,x5,x3 // compute table indice
ldr x4,[x1,x5,lsl #3]
cmp x4,#0
cinc x6,x6,eq // positions vides
beq 5f
cmp x6,#0
beq 3f // no empty left case
mov x8,#0
str x8,[x1,x5,lsl #3] // raz digit
sub x5,x5,x6
str x4,[x1,x5,lsl #3] // and store to left empty position
mov x0,#1 // move Ok
3:
cmp x7,#0 // first digit
beq 4f
cmp x10,x4 // prec digit have to add
beq 4f
sub x8,x5,#1 // prec digit
ldr x9,[x1,x8,lsl #3]
cmp x4,x9 // equal ?
bne 4f
mov x10,x4 // save digit
add x4,x4,x9 // yes -> add
str x4,[x1,x8,lsl #3]
cmp x4,#TOTAL
beq 6f
mov x4,#0
str x4,[x1,x5,lsl #3]
add x6,x6,#1 // empty case + 1
mov x0,#1 // move Ok
4:
add x7,x7,#1 // no first digit
 
5: // and loop
add x3,x3,#1
cmp x3,#SIZE
blt 2b
add x2,x2,#1
cmp x2,#SIZE
blt 1b
b 100f
6:
mov x0,#2 // total = 2048
100:
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* move right */
/******************************************************************/
/* x0 return -1 if ok */
moveRight:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
ldr x1,qAdrqTbCase
mov x0,#0
mov x2,#0
1:
mov x6,#0
mov x7,#0
mov x10,#0
mov x3,#SIZE-1
2:
lsl x5,x2,#2 // change this if size <> 4
add x5,x5,x3
ldr x4,[x1,x5,lsl #3]
cmp x4,#0
cinc x6,x6,eq // positions vides
beq 5f
 
cmp x6,#0
beq 3f // no empty right case
mov x0,#0
str x0,[x1,x5,lsl #3] // raz digit
add x5,x5,x6
str x4,[x1,x5,lsl #3] // and store to right empty position
mov x0,#1
3:
cmp x7,#0 // first digit
beq 4f
add x8,x5,#1 // next digit
ldr x9,[x1,x8,lsl #3]
cmp x4,x9 // equal ?
bne 4f
cmp x10,x4
beq 4f
mov x10,x4
add x4,x4,x9 // yes -> add
str x4,[x1,x8,lsl #3]
cmp x4,#TOTAL
beq 6f
mov x4,#0
str x4,[x1,x5,lsl #3]
add x6,x6,#1 // empty case + 1
mov x0,#1
4:
add x7,x7,#1 // no first digit
 
5: // and loop
sub x3,x3,#1
cmp x3,#0
bge 2b
add x2,x2,#1
cmp x2,#SIZE
blt 1b
b 100f
6:
mov x0,#2
100:
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* move down */
/******************************************************************/
/* x0 return -1 if ok */
moveDown:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
ldr x1,qAdrqTbCase
mov x0,#0
mov x3,#0
1:
mov x6,#0
mov x7,#0
mov x10,#0
mov x2,#SIZE-1
2:
lsl x5,x2,#2 // change this if size <> 4
add x5,x5,x3
ldr x4,[x1,x5,lsl #3]
cmp x4,#0
cinc x6,x6,eq // positions vides
beq 5f
cmp x6,#0
beq 3f // no empty right case
mov x0,#0
str x0,[x1,x5,lsl #3] // raz digit
lsl x0,x6,#2
add x5,x5,x0
str x4,[x1,x5,lsl #3] // and store to right empty position
mov x0,#1
3:
cmp x7,#0 // first digit
beq 4f
add x8,x5,#SIZE // down digit
ldr x9,[x1,x8,lsl #3]
cmp x4,x9 // equal ?
bne 4f
cmp x10,x4
beq 4f
mov x10,x4
add x4,x4,x9 // yes -> add
str x4,[x1,x8,lsl #3]
cmp x4,#TOTAL
beq 6f
mov x4,#0
str x4,[x1,x5,lsl #3]
add x6,x6,#1 // empty case + 1
mov x0,#1
4:
add x7,x7,#1 // no first digit
 
5: // and loop
sub x2,x2,#1
cmp x2,#0
bge 2b
add x3,x3,#1
cmp x3,#SIZE
blt 1b
b 100f
6:
mov x0,#2
100:
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* move up */
/******************************************************************/
/* x0 return -1 if ok */
moveUp:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
ldr x1,qAdrqTbCase
mov x0,#0
mov x3,#0
1:
mov x6,#0
mov x7,#0
mov x10,#0
mov x2,#0
2:
lsl x5,x2,#2 // change this if size <> 4
add x5,x5,x3
ldr x4,[x1,x5,lsl #3]
cmp x4,#0
cinc x6,x6,eq // positions vides
beq 5f
cmp x6,#0
beq 3f // no empty right case
mov x0,#0
str x0,[x1,x5,lsl #3] // raz digit
lsl x0,x6,#2
sub x5,x5,x0
str x4,[x1,x5,lsl #3] // and store to right empty position
mov x0,#1
3:
cmp x7,#0 // first digit
beq 4f
sub x8,x5,#SIZE // up digit
ldr x9,[x1,x8,lsl #3]
cmp x4,x9 // equal ?
bne 4f
cmp x10,x4
beq 4f
mov x10,x4
add x4,x4,x9 // yes -> add
str x4,[x1,x8,lsl #3]
cmp x4,#TOTAL
beq 6f
mov x4,#0
str x4,[x1,x5,lsl #3]
add x6,x6,#1 // empty case + 1
mov x0,#1
4:
add x7,x7,#1 // no first digit
 
5: // and loop
add x2,x2,#1
cmp x2,#SIZE
blt 2b
add x3,x3,#1
cmp x3,#SIZE
blt 1b
b 100f
6:
mov x0,#2
100:
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/******************************************************************/
/* add new digit on game */
/******************************************************************/
/* x0 return -1 if ok */
addDigit:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
sub sp,sp,#8 * SIZE*SIZE
mov fp,sp
 
mov x0,#100
bl genereraleas
cmp x0,#10
mov x1,#4
mov x5,#2
csel x5,x5,x1,ge
// movlt x5,#4
//movge x5,#2
ldr x1,qAdrqTbCase
mov x3,#0
mov x4,#0
1:
ldr x2,[x1,x3,lsl 3]
cmp x2,#0
bne 2f
str x3,[fp,x4,lsl 3]
add x4,x4,#1
2:
add x3,x3,#1
cmp x3,#SIZE*SIZE
blt 1b
cmp x4,#0 // no empty case
beq 4f
cmp x4,#1
bne 3f
ldr x2,[fp] // one case
str x5,[x1,x2,lsl 3]
mov x0,#0
b 100f
3: // multiple case
sub x0,x4,#1
bl genereraleas
ldr x2,[fp,x0,lsl 3]
str x5,[x1,x2,lsl 3]
mov x0,#0
b 100f
4:
mov x0,#-1
100:
add sp,sp,#8* (SIZE*SIZE) // stack alignement
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrqTbCase: .quad qTbCase
/******************************************************************/
/* display game */
/******************************************************************/
displayGame:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
ldr x0,qAdrszCleax1
bl affichageMess
ldr x0,qAdrszLineH
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
ldr x1,qAdrqTbCase
mov x2,#0
1:
ldr x0,[x1,x2,lsl #3]
bl digitString
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
add x2,x2,#1
cmp x2,#SIZE
blt 1b
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineH
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
2:
ldr x0,[x1,x2,lsl #3]
bl digitString
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
add x2,x2,#1
cmp x2,#SIZE*2
blt 2b
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineH
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
3:
ldr x0,[x1,x2,lsl #3]
bl digitString
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
add x2,x2,#1
cmp x2,#SIZE*3
blt 3b
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineH
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
4:
ldr x0,[x1,x2,lsl #3]
bl digitString
bl affichageMess
ldr x0,qAdrszLineV
bl affichageMess
add x2,x2,#1
cmp x2,#SIZE*4
blt 4b
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszLineVT
bl affichageMess
ldr x0,qAdrszLineH
bl affichageMess
 
100:
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrszLineH: .quad szLineH
qAdrszLineV: .quad szLineV
qAdrszLineVT: .quad szLineVT
/******************************************************************/
/* digits string */
/******************************************************************/
/* x0 contains number */
/* x0 return address string */
digitString:
stp x1,lr,[sp,-16]! // save registres
cmp x0,#0
bne 1f
ldr x0,qAdrszMess0
b 100f
1:
cmp x0,#2
bne 2f
ldr x0,qAdrszMess2
b 100f
2:
cmp x0,#4
bne 3f
ldr x0,qAdrszMess4
b 100f
3:
cmp x0,#8
bne 4f
ldr x0,qAdrszMess8
b 100f
4:
cmp x0,#16
bne 5f
ldr x0,qAdrszMess16
b 100f
5:
cmp x0,#32
bne 6f
ldr x0,qAdrszMess32
b 100f
6:
cmp x0,#64
bne 7f
ldr x0,qAdrszMess64
b 100f
7:
cmp x0,#128
bne 8f
ldr x0,qAdrszMess128
b 100f
8:
cmp x0,#256
bne 9f
ldr x0,qAdrszMess256
b 100f
9:
cmp x0,#512
bne 10f
ldr x0,qAdrszMess512
b 100f
10:
cmp x0,#1024
bne 11f
ldr x0,qAdrszMess1024
b 100f
11:
cmp x0,#2048
bne 12f
ldr x0,qAdrszMess2048
b 100f
12:
ldr x1,qAdrszMessErreur // error message
bl displayError
100:
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrszMess0: .quad szMess0
qAdrszMess2: .quad szMess2
qAdrszMess4: .quad szMess4
qAdrszMess8: .quad szMess8
qAdrszMess16: .quad szMess16
qAdrszMess32: .quad szMess32
qAdrszMess64: .quad szMess64
qAdrszMess128: .quad szMess128
qAdrszMess256: .quad szMess256
qAdrszMess512: .quad szMess512
qAdrszMess1024: .quad szMess1024
qAdrszMess2048: .quad szMess2048
 
//qAdrsBuffer: .quad sBuffer
qAdrszMessErreur : .quad szMessErreur
 
/***************************************************/
/* Generation random number */
/***************************************************/
/* x0 contains limit */
genereraleas:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
ldr x1,qAdrqGraine
ldr x2,[x1]
ldr x3,qNbDep1
mul x2,x3,x2
ldr x3,qNbDep2
add x2,x2,x3
str x2,[x1] // 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 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
 
/******************************************************************/
/* traitement du signal */
/******************************************************************/
sighandler:
stp x0,lr,[sp,-16]! // save registers
str x1,[sp,-16]!
ldr x0,qAdrqEnd
mov x1,#1 // maj zone end
str x1,[x0]
ldr x1,[sp],16
ldp x0,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/***************************************************/
/* display error message */
/***************************************************/
/* x0 contains error code x1 : message address */
displayError:
stp x2,lr,[sp,-16]! // save registers
mov x2,x0 // save error code
mov x0,x1
bl affichageMess
mov x0,x2 // error code
ldr x1,qAdrsZoneConv
bl conversion16 // conversion hexa
ldr x0,qAdrszMessErr // display error message
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc // insert result at @ character
mov x3,x0
mov x0,x2 // error code
ldr x1,qAdrsZoneConv // result address
bl conversion10S // conversion decimale
mov x0,x3
ldr x1,qAdrsZoneConv
bl strInsertAtCharInc // insert result at @ character
bl affichageMess
100:
ldp x2,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrszMessErr: .quad szMessErr
/*********************************/
/* init terminal state */
/*********************************/
initTerm:
stp x1,lr,[sp,-16]! // save registers
/* read terminal state */
mov x0,STDIN // input console
mov x1,TCGETS
ldr x2,qAdrstOldtio
mov x8,IOCTL // call system Linux
svc 0
cbnz x0,98f // error ?
 
adr x0,sighandler // adresse routine traitement signal
ldr x1,qAdrstSigAction // adresse structure sigaction
str x0,[x1,sa_handler] // maj handler
mov x0,SIGINT // signal type
ldr x1,qAdrstSigAction
mov x2,0
mov x3,8
mov x8,SIGACTION // call system
svc 0
 
cmp x0,0 // error ?
bne 98f
mov x0,SIGQUIT
ldr x1,qAdrstSigAction
mov x2,0 // NULL
mov x8,SIGACTION // call system
svc 0
cmp x0,0 // error ?
bne 98f
mov x0,SIGTERM
ldr x1,qAdrstSigAction
mov x2,0 // NULL
mov x8,SIGACTION // appel systeme
svc 0
cmp x0,0
bne 98f
//
adr x0,qAdrSIG_IGN // address signal igonre function
ldr x1,qAdrstSigAction1
str x0,[x1,sa_handler]
mov x0,SIGTTOU //invalidate other process signal
ldr x1,qAdrstSigAction1
mov x2,0 // NULL
mov x8,SIGACTION // call system
svc 0
cmp x0,0
bne 98f
//
/* read terminal current state */
mov x0,STDIN
mov x1,TCGETS
ldr x2,qAdrstCurtio // address current termio
mov x8,IOCTL // call systeme
svc 0
cmp x0,0 // error ?
bne 98f
mov x2,ICANON | ECHO // no key pressed echo on display
mvn x2,x2 // and one key
ldr x1,qAdrstCurtio
ldr x3,[x1,#term_c_lflag]
and x3,x2,x2 // add flags
str x3,[x1,#term_c_lflag] // and store
mov x0,STDIN // maj terminal current state
mov x1,TCSETS
ldr x2,qAdrstCurtio
mov x8,IOCTL // call system
svc 0
cbz x0,100f
98: // error display
ldr x1,qAdrszMessErrInitTerm
bl displayError
mov x0,-1
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrstSigAction2: .quad stSigAction2
qAdrstSigAction3: .quad stSigAction3
/*********************************/
/* init instance epool */
/*********************************/
initPoll:
stp x1,lr,[sp,-16]! // save registers
ldr x0,qAdrstevents
mov x1,STDIN // maj structure events
str x1,[x0,#poll_fd] // maj FD
mov x1,POLLIN // action code
str x1,[x0,#poll_event]
mov x0,0
mov x8,CREATPOLL // create epoll instance
svc 0
cmp x0,0 // error ?
ble 98f
mov x10,x0 // return FD epoll instance
mov x1,EPOLL_CTL_ADD
mov x2,STDIN // Fd to we want add
ldr x3,qAdrstevents // structure events address
mov x8,CTLPOLL // call system control epoll
svc 0
cmp x0,0 // error ?
blt 98f // no
mov x0,x10 // return FD epoll instance
b 100f
98: // error display
ldr x1,qAdrszMessErrInitPoll // error message
bl displayError
mov x0,-1
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/*********************************/
/* wait key */
/*********************************/
/* x0 contains FD poll */
waitKey:
stp x1,lr,[sp,-16]! // save registers
ldr x11,qAdrqTouche // key address
str xzr,[x11] // raz key
1:
ldr x1,qAdrqEnd // if signal ctrl-c -> end
ldr x1,[x1]
cbnz x1,100f
 
ldr x1,qAdrstevents
mov x2,12 // size events
mov x3,1 // timeout = 1 TODO: ??
mov x4,0
mov x8,SYSPOLL // call system wait POLL
svc 0
cmp x0,0 // key pressed ?
bge 100f
98: // error display
ldr x1,qAdrszMessErreurKey // error message
bl displayError
mov x0,-1
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/*********************************/
/* read key */
/*********************************/
/* x0 returns key value */
readKey:
stp x1,lr,[sp,-16]! // save registers
mov x0,STDIN // File Descriptor
ldr x1,qAdrqTouche // buffer address
mov x2,KEYSIZE // key size
mov x8,READ // read key
svc #0
cmp x0,0 // error ?
ble 98f
ldr x2,qAdrqTouche // key address
ldr x0,[x2]
b 100f
98: // error display
ldr x1,qAdrszMessErreur // error message
bl displayError
mov x0,-1
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/*********************************/
/* restaur terminal state */
/*********************************/
restauTerm:
stp x1,lr,[sp,-16]! // save registers
mov x0,STDIN // end then restaur begin state terminal
mov x1,TCSETS
ldr x2,qAdrstOldtio
mov x8,IOCTL // call system
svc 0
cbz x0,100f
ldr x1,qAdrszMessErreur // error message
bl displayError
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 

Ada[edit]

Works with: GNAT

with Ada.Text_IO; use Ada.Text_IO;
with System.Random_Numbers;
procedure Play_2048 is
-- ----- Keyboard management
type t_Keystroke is(Up, Down, Right, Left, Quit, Restart, Invalid);
-- Redefining this standard procedure as function to allow Get_Keystroke as an expression function
function Get_Immediate return Character is
begin
return Answer : Character do Ada.Text_IO.Get_Immediate(Answer);
endreturn;
end Get_Immediate;
Arrow_Prefix : constant Character := Character'Val(224); -- works for windows
function Get_Keystroke return t_Keystroke is
(case Get_Immediate is
when 'Q' | 'q' => Quit,
when 'R' | 'r' => Restart,
when 'W' | 'w' => Left,
when 'A' | 'a' => Up,
when 'S' | 's' => Down,
when 'D' | 'd' => Right,
-- Windows terminal
when Arrow_Prefix => (case Character'Pos(Get_Immediate)is
when72 => Up,
when75 => Left,
when77 => Right,
when80 => Down,
whenothers => Invalid),
-- Unix escape sequences
when ASCII.ESC => (case Get_Immediate is
when '[' => (case Get_Immediate is
when 'A' => Up,
when 'B' => Down,
when 'C' => Right,
when 'D' => Left,
whenothers => Invalid),
whenothers => Invalid),
whenothers => Invalid);
 
-- ----- Game data
function Random_Int isnew System.Random_Numbers.Random_Discrete(Integer);
type t_List isarray(Positive range <>)of Natural;
subtype t_Row is t_List (1..4);
type t_Board isarray(1..4)of t_Row;
Board  : t_Board;
New_Board : t_Board;
Blanks  : Natural;
Score  : Natural;
Generator : System.Random_Numbers.Generator;
 
-- ----- Displaying the board
procedure Display_Board is
Horizontal_Rule : constant String := "+----+----+----+----+";
function Center (Value : in String)return String is
((1..(2-(Value'Length-1)/2) => ' ') & -- Add leading spaces
Value(Value'First+1..Value'Last) & -- Trim the leading space of the raw number image
(1..(2-Value'Length/2) => ' ')); -- Add trailing spaces
begin
Put_Line (Horizontal_Rule);
for Row of Board loop
for Cell of Row loop
Put('|' & (if Cell = 0then" "else Center(Cell'Img)));
endloop;
Put_Line("|");
Put_Line (Horizontal_Rule);
endloop;
Put_Line("Score =" & Score'Img);
end Display_Board;
 
-- ----- Game mechanics
procedure Add_Block is
Block_Offset : Positive := Random_Int(Generator, 1, Blanks);
begin
Blanks := Blanks-1;
for Row of Board loop
for Cell of Row loop
if Cell = 0then
if Block_Offset = 1then
Cell := (if Random_Int(Generator,1,10) = 1then4else2);
return;
else
Block_Offset := Block_Offset-1;
endif;
endif;
endloop;
endloop;
end Add_Block;
 
procedure Reset_Game is
begin
Board  := (others => (others => 0));
Blanks := 16;
Score  := 0;
Add_Block;
Add_Block;
end Reset_Game;
 
-- Moving and merging will always be performed leftward, hence the following transforms
function HFlip (What : in t_Row)return t_Row is
(What(4),What(3),What(2),What(1));
function VFlip (What : in t_Board)return t_Board is
(HFlip(What(1)),HFlip(What(2)),HFlip(What(3)),HFlip(What(4)));
function Transpose (What : in t_Board)return t_Board is
begin
return Answer : t_Board do
for Row in t_Board'Rangeloop
for Column in t_Row'Rangeloop
Answer(Column)(Row) := What(Row)(Column);
endloop;
endloop;
endreturn;
end Transpose;
 
-- For moving/merging, recursive expression functions will be used, but they
-- can't contain statements, hence the following sub-function used by Merge
function Add_Blank (Delta_Score : in Natural)return t_List is
begin
Blanks := Blanks+1;
Score  := Score+Delta_Score;
return(1 => 0);
end Add_Blank;
 
function Move_Row (What : in t_List)return t_List is
(if What'Length = 1then What
elsif What(What'First) = 0
then Move_Row(What(What'First+1..What'Last)) & (1 => 0)
else(1 => What(What'First)) & Move_Row(What(What'First+1..What'Last)));
 
function Merge (What : in t_List)return t_List is
(if What'Length <= 1orelse What(What'First) = 0then What
elsif What(What'First) = What(What'First+1)
then(1 => 2*What(What'First)) & Merge(What(What'First+2..What'Last)) & Add_Blank(What(What'First))
else(1 => What(What'First)) & Merge(What(What'First+1..What'Last)));
 
function Move (What : in t_Board)return t_Board is
(Merge(Move_Row(What(1))),Merge(Move_Row(What(2))),Merge(Move_Row(What(3))),Merge(Move_Row(What(4))));
 
begin
System.Random_Numbers.Reset(Generator);
 
Main_Loop: loop
Reset_Game;
Game_Loop: loop
Display_Board;
case Get_Keystroke is
when Restart => exit Game_Loop;
when Quit => exit Main_Loop;
when Left => New_Board := Move(Board);
when Right => New_Board := VFlip(Move(VFlip(Board)));
when Up => New_Board := Transpose(Move(Transpose(Board)));
when Down => New_Board := Transpose(VFlip(Move(VFlip(Transpose(Board)))));
whenothers => null;
endcase;
 
if New_Board = Board then
Put_Line ("Invalid move...");
elsif(for some Row of New_Board => (for some Cell of Row => Cell = 2048))then
Display_Board;
Put_Line ("Win !");
exit Main_Loop;
else
Board := New_Board;
Add_Block; -- OK since the board has changed
if Blanks = 0
andthen(forall Row in1..4 =>
(forall Column in1..3 =>
(Board(Row)(Column) /= Board(Row)(Column+1))))
andthen(forall Row in1..3 =>
(forall Column in1..4 =>
(Board(Row)(Column) /= Board(Row+1)(Column))))then
Display_Board;
Put_Line ("Lost !");
exit Main_Loop;
endif;
endif;
endloop Game_Loop;
endloop Main_Loop;
end Play_2048;
 +----+----+----+----+ | 2 | 16 | 2 | 2 | +----+----+----+----+ | 64 | | | | +----+----+----+----+ | 4 | | | | +----+----+----+----+ | | | | | +----+----+----+----+ Score = 184

ALGOL 68[edit]

 
main:(
INT side = 4;
INT right = 1, up = 2, left = 3, down = 4;
[]CHAR direction letters ="ruld";
[]STRING direction descriptions =("right","up","left","down");
 
MODE BOARD =REF[,]INT;
MODE CELL =REFINT;
 
OP==(BOARD a, BOARD b)BOOL:
(FOR i TO side DOFOR j TO side DOIF a[i,j]/= b[i,j]THEN mismatch FIODOD;
TRUEEXIT
mismatch:FALSE);
 
PROC traverse board =(BOARD board,PROC(CELL)VOID callback)VOID:
FOR i FROM 1 LWB board TO 1 UPB board DO
FOR j FROM 2 LWB board TO 2 UPB board DO
callback(board[i,j])
ODOD;
 
PROC count blanks =(BOARD board)INT:
(INT count := 0;
traverse board(board,(CELL c)VOID:IF c = 0 THEN count +:= 1 FI);
count);
 
PROC nth blank=(BOARD board,INT nth) CELL:
(CELL result;
INT count := 0;
traverse board(board,(CELL c)VOID:
(IF c = 0 THEN count +:= 1 FI;
IF count = nth THEN
result := c; return
FI));
return: result);
 
PROC add new number =(BOARD board)VOID:
(INT nblanks = count blanks(board);
INT number :=(random >=.9| 4 | 2);
INT position :=ENTIER(random * nblanks)+ 1;
 
nth blank(board, position):= number);
 
PROC shift =(REF[]INT row,BOOL to the end)VOID:
(INT from =(to the end |UPB row |LWB row),
to =(to the end |LWB row |UPB row),
dir =(to the end |-1 | 1);
FOR i FROM from + dir BY dir TO to DO
IF row[i]/= 0 THEN
INTblank:= 0;
FOR j FROM i - dir BY-dir TO from WHILE row[j]= 0 DO
blank:= j
OD;
IFblank/= 0 THEN
row[blank]:= row[i];
row[i]:= 0
FI
FI
OD);
 
PROC combine =(REF[]INT row,BOOL to the end)VOID:
(INT from =(to the end |UPB row |LWB row),
to =(to the end |LWB row |UPB row),
dir =(to the end |-1 | 1);
FOR i FROM from BY dir TO to - dir DO
IF row[i]/= 0 AND row[i]= row[i+dir]THEN
row[i]*:= 2;
row[i+dir]:= 0
FI
OD);
 
PROC move =(BOARD board,INT direction)VOID:
FOR i TO side DO
CASE direction IN
# right #(shift(board[i,],TRUE); combine(board[i,],TRUE); shift(board[i,],TRUE)),
# up #(shift(board[,i],FALSE); combine(board[,i],FALSE); shift(board[,i],FALSE)),
# left #(shift(board[i,],FALSE); combine(board[i,],FALSE); shift(board[i,],FALSE)),
# down #(shift(board[,i],TRUE); combine(board[,i],TRUE); shift(board[,i],TRUE))
ESAC
OD;
 
PROCprint board =(BOARD board)VOID:
(FOR i FROM 1 LWB board TO 1 UPB board DO
print("+");
FOR j FROM 2 LWB board TO 2 UPB board DOprint("------+")OD;
print((new line,"|"));
FOR j FROM 2 LWB board TO 2 UPB board DO
print(((board[i,j]= 0 |" "|whole(board[i,j],-5))," |"))
OD;
print(new line)
OD;
print("+");FOR j FROM 2 LWB board TO 2 UPB board DOprint("------+")OD;
print(new line)
);
 
PROC score =(BOARD board)INT:
(INT result := 0;
traverse board(board,(CELL c)VOID: result +:= c);
result);
 
PROC join =([]STRING strings,STRING joiner)STRING:
IFUPB strings > 0 THEN
STRING result := strings[1];
FOR i FROM 2 TOUPB strings DO result +:= joiner +:= strings[i]OD;
result
ELSE
""
FI;
 
BOARD board =LOC[side,side]INT;
BOARD previous =LOC[side,side]INT;
 
traverse board(board,(CELL c)VOID: c := 0);
 
# start with two numbers #
TO 2 DO add new number(board)OD;
 
# play! #
STRING prompt :="enter one of ["+ direction letters +"] (for "+ join(direction descriptions,"/")+"): ";
DO
CHAR key;
INT dir;
print board(board);
print(("score: ",whole(score(board),0),new line));
WHILE
print(prompt);
read((key,new line));
NOTchar in string(key, dir, direction letters)
DOSKIPOD;
previous := board;
move(board, dir);
IF count blanks(board)= 0 THEN lose FI;
traverse board(board,(CELL c)VOID:IF c = 2048 THEN win FI);
IF previous = board THEN
print(("try again!",new line))
ELSE
add new number(board)
FI
OD;
 
win:print board(board);print(("you win!",new line))EXIT
lose:print(("you lose!",new line))
)
 

APPLESOFT[edit]

PRINT "Game 2048"
 
10 REM ************
20 REM * 2024 *
30 REM ************
40 HOME
100 W = 2: REM **** W=0 FOR LOOSE W=1 FOR WIN W=2 FOR PLAYING ****
110 DIM MA(4,4)
120 FC = 16: REM FREECELLS
130 A$ = "":SC = 0:MT = 2
140 GOSUB 1000: DRAW THESCREEN
150 GOSUB 1500: REM PRINT SCORE AND MAXTILE
160 GOSUB 1700: REM BREED
170 GOSUB 2000: REM PRINT SCORES IN THE MATRIX AND CALC FC AND MT
200 REM ******************
210 REM MAIN PROGRAM
220 REM ******************
230 HTAB 38: VTAB 22
235 IF W < 2 THEN GOTO 950: REM ******* END GAME ********
240 WAIT - 16384,128:A = PEEK ( - 16384) - 128 - 68: POKE - 16368,0
250 ON A GOTO 999,900,900,900,300,350,400,900,450
280 REM ************************
285 REM FOLLOWING LINES HANDLE THE UP, LEFT, RIGHT, DOWN, NOP, EXIT
290 REM ************************
300 GOSUB 2500: GOSUB 3500: GOSUB 2500: GOSUB 1700: GOSUB 2000: GOSUB 1
500
310 GOTO 200
350 GOSUB 2600: GOSUB 3600: GOSUB 2600: GOSUB 1700: GOSUB 2000: GOSUB 1
500
360 GOTO 200
400 GOSUB 2700: GOSUB 3700: GOSUB 2700: GOSUB 1700: GOSUB 2000: GOSUB 1
500
410 GOTO 200
450 GOSUB 2800: GOSUB 3800: GOSUB 2800: GOSUB 1700: GOSUB 2000: GOSUB 1
500
460 GOTO 200
900 GOTO 200
950 HOME : VTAB 10
960 PRINT " ********************"
970 IF W = 1 THEN PRINT " * YOU WIN *"
980 IF W = 0 THEN PRINT " * YOU LOOSE *"
990 PRINT " ********************"
995 PRINT " SCORE =";SC
996 PRINT " MAXTILE=";MT
999 END
1000 REM DRAW FRAME + SCORE
1010 FOR I = 1 TO 5
1020 VTAB 1 + (I - 1) * 4: PRINT "---------------------"
1030 NEXT I
1040 FOR I = 1 TO 4
1050 FOR J = 1 TO 3
1060 VTAB 1 + (I - 1) * 4 + J: PRINT "| | | | |"
1070 NEXT J
1080 NEXT I
1090 HTAB 30: VTAB 3: PRINT "I";
1100 HTAB 30: VTAB 9: PRINT "M";
1110 HTAB 25: VTAB 6: PRINT "J";
1120 HTAB 35: VTAB 6: PRINT "K";
1130 HTAB 25: VTAB 12: PRINT "E = END"
1140 HTAB 25: VTAB 14: PRINT "SCORE:"
1150 HTAB 25: VTAB 16: PRINT "MAXTILE:"
1160 HTAB 1: VTAB 19: PRINT "YOU CAN SLIDE THE NUMBERS IN THE MATRIX"
1170 HTAB 1: VTAB 20: PRINT "BY PRESSING IJKM. WHEN MATCHING NUMBERS"
1180 HTAB 1: VTAB 21: PRINT "MEET THEY COMBINE IN THE SUM"
1190 HTAB 1: VTAB 22: PRINT "TO WIN YOU HAVE TO REACH THE SUM 2048"
1200 RETURN
1500 REM ***************
1501 REM PRINT SCORE + MAXTILE
1502 REM ***************
1510 VTAB 14: HTAB 32:
1520 SC$ = STR$ (SC):LS = LEN (SC$)
1530 FOR I = 1 TO 7 - LS: PRINT " ";: NEXT I
1540 PRINT SC$
1550 VTAB 16: HTAB 34:
1560 MT$ = STR$ (MT):LS = LEN (MT$)
1570 FOR I = 1 TO 5 - LS: PRINT " ";: NEXT I
1580 PRINT MT$
1590 IF SC = 2048 THEN W = 1: REM ******** YOU WIN ********
1690 RETURN
1700 REM ****************
1701 REM PUT A "2" IN A RANDOM EMPTY CELL
1702 REM ****************
1708 IF FC = 0 THEN W = 0: GOTO 1800: REM ***** YOU LOOSE *****
1710 K = INT ( RND (1) * FC + 1)
1720 N = 0
1730 FOR I = 1 TO 4
1740 FOR J = 1 TO 4
1750 IF MA(I,J) = 0 THEN N = N + 1
1760 IF N = K THEN MA(I,J) = 2:FC = FC - 1:I = 4:J = 4
1780 NEXT J
1790 NEXT I
1800 RETURN
2000 REM *************
2001 REM WRITE THE CELL CONTENT AND CALC. FREECELLS AND MAXTILE
2002 REM *************
2005 FC = 0:MT = 0: REM INITIALIZE FREECELLS AND MAXTILES
2010 FOR I = 1 TO 4
2020 FOR J = 1 TO 4
2030 HTAB 2 + (J - 1) * 5: VTAB 3 + (I - 1) * 4
2040 PRINT " ";: HTAB 2 + (J - 1) * 5
2050 IF MA(I,J) = 0 THEN FC = FC + 1: GOTO 2060
2055 PRINT MA(I,J);
2060 IF MA(I,J) > MT THEN MT = MA(I,J)
2090 NEXT J
2100 NEXT I
2190 RETURN
2500 REM *****************
2510 REM COMPACT UP - KIND OF BUBBLE SORT
2520 REM *****************
2530 FOR J = 1 TO 4
2540 FOR K = 3 TO 1 STEP - 1
2550 FOR I = 1 TO K
2560 IF MA(I,J) = 0 THEN MA(I,J) = MA(I + 1,J):MA(I + 1,J) = 0
2570 NEXT : NEXT : NEXT
2590 RETURN
2600 REM ************
2610 REM COMPACT LEFT
2620 REM ************
2630 FOR I = 1 TO 4
2640 FOR K = 3 TO 1 STEP - 1
2650 FOR J = 1 TO K
2660 IF MA(I,J) = 0 THEN MA(I,J) = MA(I,J + 1):MA(I,J + 1) = 0
2670 NEXT : NEXT : NEXT
2690 RETURN
2700 REM ************
2710 REM COMPACT RIGHT
2720 REM ************
2730 FOR I = 1 TO 4
2740 FOR K = 2 TO 4
2750 FOR J = 4 TO K STEP - 1
2760 IF MA(I,J) = 0 THEN MA(I,J) = MA(I,J - 1):MA(I,J - 1) = 0
2770 NEXT : NEXT : NEXT
2790 RETURN
2800 REM *****************
2810 REM COMPACT DOWN
2820 REM *****************
2830 FOR J = 1 TO 4
2840 FOR K = 2 TO 4
2850 FOR I = 4 TO K STEP - 1
2860 IF MA(I,J) = 0 THEN MA(I,J) = MA(I - 1,J):MA(I - 1,J) = 0
2870 NEXT : NEXT : NEXT
2890 RETURN
3500 REM ***************
3510 REM ADD UP
3520 REM ***************
3530 FOR J = 1 TO 4
3540 FOR I = 1 TO 3
3550 IF MA(I,J) = MA(I + 1,J) THEN MA(I,J) = MA(I,J) * 2:MA(I + 1,J) =
0:SC = SC + MA(I,J)
3560 NEXT : NEXT
3590 RETURN
3600 REM **************
3610 REM SUM LEFT
3620 REM **************
3630 FOR I = 1 TO 4
3640 FOR J = 1 TO 3
3650 IF MA(I,J) = MA(I,J + 1) THEN MA(I,J) = MA(I,J) * 2:MA(I,J + 1) =
0:SC = SC + MA(I,J)
3660 NEXT : NEXT
3690 RETURN
3700 REM **************
3710 REM SUM RIGHT
3720 REM **************
3730 FOR I = 1 TO 4
3740 FOR J = 4 TO 2 STEP - 1
3750 IF MA(I,J) = MA(I,J - 1) THEN MA(I,J) = MA(I,J) * 2:MA(I,J - 1) =
0:SC = SC + MA(I,J)
3760 NEXT : NEXT
3790 RETURN
3800 REM ***************
3810 REM ADD DOWN
3820 REM ***************
3830 FOR J = 1 TO 4
3840 FOR I = 4 TO 2 STEP - 1
3850 IF MA(I,J) = MA(I - 1,J) THEN MA(I,J) = MA(I,J) * 2:MA(I - 1,J) =
0:SC = SC + MA(I,J)
3860 NEXT : NEXT
3890 RETURN
 
-----
it runs somehow slowly but still fun to play. The only non standard basic is the input routine which reads directly the memory location (line 240) instead of using "input" od "get"
 
---------------------
| | | | |
|4 | | |2 | I
| | | | |
---------------------
| | | | | J K
|4 |2 | | |
| | | | |
--------------------- M
| | | | |
|2 |16 |4 | |
| | | | | E = END
---------------------
| | | | | SCORE: 4924
|128 |512 | | |
| | | | | MAXTILE: 512
---------------------
 
YOU CAN SLIDE THE NUMBERS IN THE MATRIX
BY PRESSING IJKM. WHEN MATCHING NUMBERS
MEET THEY COMBINE IN THE SUM
TO WIN YOU HAVE TO REACH THE SUM 2048
 
 
 

ARM Assembly[edit]

Works with: as version Raspberry Pi

 
/* ARM assembly Raspberry PI */
/* program 2048.s */
 
/* REMARK 1: this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ STDIN,0 @ Linux input console
.equ READ,3 @ Linux syscall
.equ SIZE,4
.equ TOTAL,2048
.equ BUFFERSIZE,80
 
.equ IOCTL,0x36 @ Linux syscall
.equ SIGACTION,0x43 @ Linux syscall
.equ SYSPOLL,0xA8 @ Linux syscall
 
.equ TCGETS,0x5401
.equ TCSETS,0x5402
.equ ICANON,2
.equ ECHO,10
.equ POLLIN,1
 
.equ SIGINT,2 @ Issued if the user sends an interrupt signal (Ctrl + C)
.equ SIGQUIT,3 @ Issued if the user sends a quit signal (Ctrl + D)
.equ SIGTERM,15 @ Software termination signal (sent by kill by default)
.equ SIGTTOU,22
 
/*******************************************/
/* Structures */
/********************************************/
/* structure termios see doc linux*/
.struct 0
term_c_iflag: @ input modes
.struct term_c_iflag +4
term_c_oflag: @ output modes
.struct term_c_oflag +4
term_c_cflag: @ control modes
.struct term_c_cflag +4
term_c_lflag: @ local modes
.struct term_c_lflag +4
term_c_cc: @ special characters
.struct term_c_cc +20 @ see length if necessary
term_fin:
 
/* structure sigaction see doc linux */
.struct 0
sa_handler:
.struct sa_handler +4
sa_mask:
.struct sa_mask +4
sa_flags:
.struct sa_flags +4
sa_sigaction:
.struct sa_sigaction +4
sa_fin:
 
/* structure poll see doc linux */
.struct 0
poll_fd: @ File Descriptor
.struct poll_fd +4
poll_events: @ events mask
.struct poll_events +4
poll_revents: @ events returned
.struct poll_revents +4
poll_fin:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessOK:.asciz "Bravo !! You win. \n"
szMessNotOK:.asciz "You lost !! \n"
szMessNewGame:.asciz "New game (y/n) ? \n"
szMessErreur:.asciz "Error detected.\n"
szCarriageReturn:.asciz "\n"
//szMessMovePos:.asciz "\033[00;00H"
szMess0:.asciz " "
szMess2:.asciz " 2 "
szMess4:.asciz " 4 "
szMess8:.asciz " 8 "
szMess16:.asciz " 16 "
szMess32:.asciz " 32 "
szMess64:.asciz " 64 "
szMess128:.asciz " 128 "
szMess256:.asciz " 256 "
szMess512:.asciz " 512 "
szMess1024:.asciz " 1024 "
szMess2048:.asciz " 2048 "
szClear1:.byte 0x1B
.byte 'c' @ other console clear
.byte 0
 
szLineH:.asciz "-----------------------------\n"
szLineV:.asciz "|"
szLineVT:.asciz "| | | | |\n"
.align 4
iGraine:.int 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv:.skip 24
sBuffer:.skip BUFFERSIZE
iTbCase:.skip 4* SIZE * SIZE
iEnd:.skip 4 @ 0 loop 1 = end loop
iTouche:.skip 4 @ value key pressed
stOldtio:.skip term_fin @ old terminal state
stCurtio:.skip term_fin @ current terminal state
stSigAction:.skip sa_fin @ area signal structure
stSigAction1:.skip sa_fin
stPoll1:.skip poll_fin @ area poll structure
stPoll2:.skip poll_fin
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
 
1: @ begin game loop
ldrr0,iAdrszClear1
bl affichageMess
bl razTable
2:
bl addDigit
cmpr0,#-1
beq5f @ end game
bl displayGame
3:
bl readKey
cmpr0,#-1
beq100f @ error or control-c
bl keyMove
cmpr0,#0
beq 3b @ no change -> loop
cmpr0,#2 @ last addition = 2048 ?
beq4f
cmpr0,#-1 @ quit ?
bne 2b @ loop
 
b10f
4: @ last addition = 2048
ldrr0,iAdrszMessOK
bl affichageMess
b10f
5: @ display message no solution
ldrr0,iAdrszMessNotOK
bl affichageMess
 
10: @ display new game ?
ldrr0,iAdrszCarriageReturn
bl affichageMess
ldrr0,iAdrszMessNewGame
bl affichageMess
bl readKey
ldrr0,iAdriTouche
ldrbr0,[r0]
cmpr0,#'y'
beq1b
cmpr0,#'Y'
beq1b
 
100: @ standard end of the program
movr0, #0 @ return code
movr7, #EXIT @ request to exit program
svc #0 @ perform the system call
 
iAdrszCarriageReturn:.int szCarriageReturn
iAdrszMessNotOK:.int szMessNotOK
iAdrszMessOK:.int szMessOK
iAdrszMessNewGame:.int szMessNewGame
iAdrsZoneConv:.int sZoneConv
iAdrszClear1:.int szClear1
/******************************************************************/
/* raz table cases */
/******************************************************************/
razTable:
push{r0-r2,lr} @ save registers
ldrr1,iAdriTbCase
movr0,#0
movr2,#0
1:
strr0,[r1,r2,lsl #2]
addr2,r2,#1
cmpr2,#SIZE * SIZE
blt1b
100:
pop{r0-r2,lr} @ restaur registers
bxlr @return
/******************************************************************/
/* key move */
/******************************************************************/
/*r0 contains key value */
keyMove:
push{r1,lr} @ save registers
cmpr0,#0x42 @ down arrow
bne1f
bl moveDown
b100f
1:
cmpr0,#0x41 @ high arrow
bne2f
bl moveUp
b100f
2:
cmpr0,#0x43 @ right arrow
bne3f
bl moveRight
b100f
3:
cmpr0,#0x44 @ left arrow
bne4f
bl moveLeft
b100f
4:
ldrr0,iAdriTouche
ldrbr0,[r0]
cmpr0,#'q' @ quit game
bne5f
movr0,#-1
b100f
5:
cmpr0,#'Q' @ quit game
bne100f
movr0,#-1
b100f
 
100:
pop{r1,lr} @ restaur registers
bxlr @return
/******************************************************************/
/* move left */
/******************************************************************/
/*r0 return -1 if ok */
moveLeft:
push{r1-r10,lr} @ save registers
ldrr1,iAdriTbCase
movr0,#0 @ top move Ok
movr2,#0 @ line indice
1:
movr6,#0 @ counter empty case
movr7,#0 @ first digit
movr10,#0 @ last digit to add
movr3,#0 @ column indice
2:
lslr5,r2,#2 @ change this if size <> 4
addr5,r5,r3 @ compute table indice
ldrr4,[r1,r5,lsl #2]
cmpr4,#0
addeqr6,r6,#1 @ positions vides
beq5f
cmpr6,#0
beq3f @ no empty left case
movr8,#0
strr8,[r1,r5,lsl #2] @ raz digit
subr5,r5,r6
strr4,[r1,r5,lsl #2] @ and store to left empty position
movr0,#1 @ move Ok
//subr6,r6,#1
3:
cmpr7,#0 @ first digit
beq4f
cmpr10,r4 @ prec digit have to add
beq4f
subr8,r5,#1 @ prec digit
ldrr9,[r1,r8,lsl #2]
cmpr4,r9 @ equal ?
bne4f
movr10,r4 @ save digit
addr4,r4,r9 @ yes -> add
strr4,[r1,r8,lsl #2]
cmpr4,#TOTAL
moveqr0,#2
beq100f
movr4,#0
strr4,[r1,r5,lsl #2]
addr6,r6,#1 @ empty case +1
movr0,#1 @ move Ok
4:
addr7,r7,#1 @ no first digit
 
5: @ and loop
addr3,r3,#1
cmpr3,#SIZE
blt 2b
addr2,r2,#1
cmpr2,#SIZE
blt1b
100:
pop{r1-r12,lr}
bxlr @ return
/******************************************************************/
/* move right */
/******************************************************************/
/*r0 return -1 if ok */
moveRight:
push{r1-r5,lr} @ save registers
ldrr1,iAdriTbCase
movr0,#0
movr2,#0
1:
movr6,#0
movr7,#0
movr10,#0
movr3,#SIZE-1
2:
lslr5,r2,#2 @ change this if size <> 4
addr5,r5,r3
ldrr4,[r1,r5,lsl #2]
cmpr4,#0
addeqr6,r6,#1 @ positions vides
beq5f
 
cmpr6,#0
beq3f @ no empty right case
movr0,#0
strr0,[r1,r5,lsl #2] @ raz digit
addr5,r5,r6
strr4,[r1,r5,lsl #2] @ and store to right empty position
movr0,#1
3:
cmpr7,#0 @ first digit
beq4f
addr8,r5,#1 @ next digit
ldrr9,[r1,r8,lsl #2]
cmpr4,r9 @ equal ?
bne4f
cmpr10,r4
beq4f
movr10,r4
addr4,r4,r9 @ yes -> add
strr4,[r1,r8,lsl #2]
cmpr4,#TOTAL
moveqr0,#2
beq100f
movr4,#0
strr4,[r1,r5,lsl #2]
addr6,r6,#1 @ empty case +1
movr0,#1
4:
addr7,r7,#1 @ no first digit
 
5: @ and loop
subr3,r3,#1
cmpr3,#0
bge 2b
addr2,r2,#1
cmpr2,#SIZE
blt1b
 
100:
pop{r1-r5,lr}
bxlr @ return
/******************************************************************/
/* move down */
/******************************************************************/
/*r0 return -1 if ok */
moveDown:
push{r1-r5,lr} @ save registers
ldrr1,iAdriTbCase
movr0,#0
movr3,#0
1:
movr6,#0
movr7,#0
movr10,#0
movr2,#SIZE-1
2:
lslr5,r2,#2 @ change this if size <> 4
addr5,r5,r3
ldrr4,[r1,r5,lsl #2]
cmpr4,#0
addeqr6,r6,#1 @ positions vides
beq5f
cmpr6,#0
beq3f @ no empty right case
movr0,#0
strr0,[r1,r5,lsl #2] @ raz digit
lslr0,r6,#2
addr5,r5,r0
strr4,[r1,r5,lsl #2] @ and store to right empty position
movr0,#1
3:
cmpr7,#0 @ first digit
beq4f
addr8,r5,#SIZE @ down digit
ldrr9,[r1,r8,lsl #2]
cmpr4,r9 @ equal ?
bne4f
cmpr10,r4
beq4f
movr10,r4
addr4,r4,r9 @ yes -> add
strr4,[r1,r8,lsl #2]
cmpr4,#TOTAL
moveqr0,#2
beq100f
movr4,#0
strr4,[r1,r5,lsl #2]
addr6,r6,#1 @ empty case +1
movr0,#1
4:
addr7,r7,#1 @ no first digit
 
5: @ and loop
subr2,r2,#1
cmpr2,#0
bge 2b
addr3,r3,#1
cmpr3,#SIZE
blt1b
 
100:
pop{r1-r5,lr}
bxlr @ return
/******************************************************************/
/* move up */
/******************************************************************/
/*r0 return -1 if ok */
moveUp:
push{r1-r5,lr} @ save registers
ldrr1,iAdriTbCase
movr0,#0
movr3,#0
1:
movr6,#0
movr7,#0
movr10,#0
movr2,#0
2:
lslr5,r2,#2 @ change this if size <> 4
addr5,r5,r3
ldrr4,[r1,r5,lsl #2]
cmpr4,#0
addeqr6,r6,#1 @ positions vides
beq5f
cmpr6,#0
beq3f @ no empty right case
movr0,#0
strr0,[r1,r5,lsl #2] @ raz digit
lslr0,r6,#2
subr5,r5,r0
strr4,[r1,r5,lsl #2] @ and store to right empty position
movr0,#1
3:
cmpr7,#0 @ first digit
beq4f
subr8,r5,#SIZE @ up digit
ldrr9,[r1,r8,lsl #2]
cmpr4,r9 @ equal ?
bne4f
cmpr10,r4
beq4f
movr10,r4
addr4,r4,r9 @ yes -> add
strr4,[r1,r8,lsl #2]
cmpr4,#TOTAL
moveqr0,#2
beq100f
movr4,#0
strr4,[r1,r5,lsl #2]
addr6,r6,#1 @ empty case +1
movr0,#1
4:
addr7,r7,#1 @ no first digit
 
5: @ and loop
addr2,r2,#1
cmpr2,#SIZE
blt 2b
addr3,r3,#1
cmpr3,#SIZE
blt1b
 
100:
pop{r1-r5,lr}
bxlr @ return
/******************************************************************/
/*add new digit on game */
/******************************************************************/
/*r0 return -1 if ok */
addDigit:
push{r1-r5,lr} @ save registers
subsp,#4* SIZE*SIZE
movfp,sp
 
movr0,#100
bl genereraleas
cmpr0,#10
movltr5,#4
movger5,#2
ldrr1,iAdriTbCase
movr3,#0
movr4,#0
1:
ldrr2,[r1,r3,lsl #2]
cmpr2,#0
bne2f
strr3,[fp,r4,lsl #2]
addr4,r4,#1
2:
addr3,r3,#1
cmpr3,#SIZE*SIZE
blt1b
cmpr4,#0 @ no empty case
moveqr0,#-1
beq100f
cmpr4,#1
bne3f
ldrr2,[fp] @ one case
strr5,[r1,r2,lsl #2]
movr0,#0
b100f
3: @ multiple case
subr0,r4,#1
bl genereraleas
ldrr2,[fp,r0,lsl #2]
strr5,[r1,r2,lsl #2]
movr0,#0
 
100:
addsp,#4*(SIZE*SIZE) @ stack alignement
pop{r1-r5,lr}
bxlr @ return
iAdriTbCase:.int iTbCase
/******************************************************************/
/* display game */
/******************************************************************/
displayGame:
push{r1-r3,lr} @ save registers
ldrr0,iAdrszClear1
bl affichageMess
ldrr0,iAdrszLineH
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
ldrr1,iAdriTbCase
movr2,#0
1:
ldrr0,[r1,r2,lsl #2]
bl digitString
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
addr2,r2,#1
cmpr2,#SIZE
blt1b
ldrr0,iAdrszCarriageReturn
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineH
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
2:
ldrr0,[r1,r2,lsl #2]
bl digitString
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
addr2,r2,#1
cmpr2,#SIZE*2
blt 2b
ldrr0,iAdrszCarriageReturn
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineH
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
3:
ldrr0,[r1,r2,lsl #2]
bl digitString
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
addr2,r2,#1
cmpr2,#SIZE*3
blt 3b
ldrr0,iAdrszCarriageReturn
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineH
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
4:
ldrr0,[r1,r2,lsl #2]
bl digitString
bl affichageMess
ldrr0,iAdrszLineV
bl affichageMess
addr2,r2,#1
cmpr2,#SIZE*4
blt 4b
ldrr0,iAdrszCarriageReturn
bl affichageMess
ldrr0,iAdrszLineVT
bl affichageMess
ldrr0,iAdrszLineH
bl affichageMess
 
100:
pop{r1-r3,lr}
bxlr @ return
iAdrszLineH:.int szLineH
iAdrszLineV:.int szLineV
iAdrszLineVT:.int szLineVT
//iAdrszMessMovePos:.int szMessMovePos
/******************************************************************/
/* digits string */
/******************************************************************/
/*r0 contains number */
/*r0 return address string */
digitString:
push{r1,lr} @ save registers
cmpr0,#0
bne1f
ldrr0,iAdrszMess0
b100f
1:
cmpr0,#2
bne2f
ldrr0,iAdrszMess2
b100f
2:
cmpr0,#4
bne3f
ldrr0,iAdrszMess4
b100f
3:
cmpr0,#8
bne4f
ldrr0,iAdrszMess8
b100f
4:
cmpr0,#16
bne5f
ldrr0,iAdrszMess16
b100f
5:
cmpr0,#32
bne6f
ldrr0,iAdrszMess32
b100f
6:
cmpr0,#64
bne7f
ldrr0,iAdrszMess64
b100f
7:
cmpr0,#128
bne8f
ldrr0,iAdrszMess128
b100f
8:
cmpr0,#256
bne9f
ldrr0,iAdrszMess256
b100f
9:
cmpr0,#512
bne10f
ldrr0,iAdrszMess512
b100f
10:
cmpr0,#1024
bne11f
ldrr0,iAdrszMess1024
b100f
11:
cmpr0,#2048
bne12f
ldrr0,iAdrszMess2048
b100f
12:
ldrr1,iAdrszMessErreur @ error message
bl displayError
100:
pop{r1,lr}
bxlr @ return
iAdrszMess0:.int szMess0
iAdrszMess2:.int szMess2
iAdrszMess4:.int szMess4
iAdrszMess8:.int szMess8
iAdrszMess16:.int szMess16
iAdrszMess32:.int szMess32
iAdrszMess64:.int szMess64
iAdrszMess128:.int szMess128
iAdrszMess256:.int szMess256
iAdrszMess512:.int szMess512
iAdrszMess1024:.int szMess1024
iAdrszMess2048:.int szMess2048
 
//iAdrsBuffer:.int sBuffer
/***************************************************/
/* Generation random number */
/***************************************************/
/*r0 contains limit */
genereraleas:
push{r1-r4,lr} @ save registers
ldrr4,iAdriGraine
ldrr2,[r4]
ldrr3,iNbDep1
mulr2,r3,r2
ldrr3,iNbDep2
addr2,r2,r3
strr2,[r4] @ maj de la graine pour l appel suivant
cmpr0,#0
beq100f
addr1,r0,#1 @ divisor
movr0,r2 @ dividende
bl division
movr0,r3 @ résult = remainder
 
100: @ end function
pop{r1-r4,lr} @ restaur registers
bxlr @ return
/*****************************************************/
iAdriGraine:.int iGraine
iNbDep1:.int 0x343FD
iNbDep2:.int 0x269EC3
/***************************************************/
/* read touch */
/***************************************************/
readKey:
push{r1-r7,lr}
movr5,#0
ldrr1,iAdriTouche @ buffer address
strr5,[r1] @ raz
Sours: https://rosettacode.org/wiki/2048

2048 Game in Python

In this article we will look python code and logic to design a 2048 game you have played very often in your smartphone. If you are not familiar with the game, it is highly recommended to first play the game so that you can understand the basic functioning of it.

How to play 2048 :

 Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.  

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning - Basic Level Course

1. There is a 4*4 grid which can be filled with any number. Initially two random cells are filled with 2 in it. Rest cells are empty.

2. we have to press any one of four keys to move up, down, left, or right. When we press any key, the elements of the cell move in that direction such that if any two identical numbers are contained in that particular row (in case of moving left or right) or column (in case of moving up and down) they get add up and extreme cell in that direction fill itself with that number and rest cells goes empty again.

3. After this grid compression any random empty cell gets itself filled with 2.

4. Following the above process we have to double the elements by adding up and make 2048 in any of the cell. If we are able to do that we wins.

5. But if during the game there is no empty cell left to be filled with a new 2, then the game goes over.

In above process you can see the snapshots from graphical user interface of 2048 game. But all the logic lies in the main code. So to solely understand the logic behind it we can assume the above grid to be a 4*4 matrix ( a list with four rows and four columns). You can see below the way to take input and output without GUI for the above game.

Example : 

Commands are as follows : 'W' or 'w' : Move Up 'S' or 's' : Move Down 'A' or 'a' : Move Left 'D' or 'd' : Move Right [0, 0, 0, 0] [0, 0, 0, 0] [0, 0, 0, 0] [0, 0, 2, 0] Press the command : a GAME NOT OVER [0, 0, 0, 2] [0, 0, 0, 0] [0, 0, 0, 0] [2, 0, 0, 0] Press the command : s GAME NOT OVER [0, 0, 0, 0] [0, 0, 0, 0] [0, 0, 2, 0] [2, 0, 0, 2] Press the command : d GAME NOT OVER [0, 0, 0, 0] [0, 0, 0, 0] [2, 0, 0, 2] [0, 0, 0, 4] Press the command : a GAME NOT OVER [0, 2, 0, 0] [0, 0, 0, 0] [4, 0, 0, 0] [4, 0, 0, 0] Press the command : s GAME NOT OVER [0, 0, 0, 0] [0, 0, 0, 0] [0, 0, 0, 0] [8, 2, 0, 2] . . . And the series of input output will go on till we lose or win!

Programming Approach : 

  1. We will design each logic function such as we are performing a left swipe then we will use it for right swipe by reversing matrix and performing left swipe.
  2. Moving up can be done by taking transpose then moving left.
  3. Moving down can be done by taking transpose the moving right.
  4. All the logic in the program are explained in detail in the comments. Highly recommended to go through all the comments.

We have two python files below, one is 2048.py which contains main driver code and the other is logic.py which contains all functions used. logic.py should be imported in 2048.py to use these functions. just place both the files in the same folder then run 2048.py will work perfectly.

logic.py  

Python3

 
 
 
 
 
 

Python3

 
 
 
 
 
 

2048.py 

Python3

 

Output :




My Personal Notesarrow_drop_up
Sours: https://www.geeksforgeeks.org/2048-game-in-python/
  1. Ultimate skyrim vs requiem
  2. Ark valguero creatures
  3. Unlocked s20 on verizon

2048

A small clone of 1024, based on Saming's 2048 (also a clone).

Made just for fun. Play it here!

The official app can also be found on the Play Store and App Store!

Contributions

Anna Harren and sigod are maintainers for this repository.

Other notable contributors:

Many thanks to rayhaanj, Mechazawa, grant, remram44 and ghoullier for the many other good contributions.

Screenshot

Screenshot

That screenshot is fake, by the way. I never reached 2048

Contributing

Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into ! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process.

You can find the same information in the contributing guide.

License

2048 is licensed under the MIT license.

Donations

I made this in my spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying me coffee, you can donate at my BTC address: . Thank you very much!

Sours: https://github.com/gabrielecirulli/2048

Half an hour later, the body on the bike was riding towards me. Zoya. - I already meet the second bus. Have you brought the wine.

Code 2048

Her life. In one of the packages, I unexpectedly noticed the same Svetkin training suit. And something exploded in me. It got hot, easy and somehow.

How to redeem diamonds from 2048 cube winner - 2048 CUBE WINNER APP REAL OR FAKE WINNER FREE FIRE

Envy. Vika laughed. And I liked to empty his balls with you like this. After you, the taste of his semen is completely different. Some kind of saturated and more liquid.

Now discussing:

I could swear it was my damaged guide. They followed me. Chapter 6 Creena slept. I kicked off my shoes at the door, tiptoed into the room, closed the door and lit the candles.



261 262 263 264 265