Assignment 

BLACKJACK GAME ( GRAPHICAL)

  1. create the “class” card. optionally inherit from class obj

write a method to draw the cards.

Create a constructor method card.card for initializing each card.

write a main program to clear the screen and draw one deck of cards overlapped in rows.

Code the Galois LFSR PRNG function; (it holds the number in the global section)

  1. Populate an array of pointers (the size should be 52 times the number of decks (1-9) as determined by the difficulty)

Use dynamic allocation to create each card, meaning have a card.new method that allocates the space and”falls into” the constructor card.card that will populate the instance.

  1. After the array is populated, shuffle the array using the following algorithm:

if n is the user input difficulty, N = 2<<n;
void Shuffle(int array[ ]:a0, int N:a1)
{

do {

int t0 = lfsr() % a1;
int t2 = array[t0];
int t3 =array[–a1];
array[t0] = t3;
array[a1] = t2;

}while (a1>0);

}

  1. Add a boolean data member to your card or obj class to allow the object to hide. Hidden objects wont be drawn. hide all of the cards in the shoe except for the top one. (and even that should be face down)
  2. Show the Deck in one corner of the screen (face down), “Deal” a card by moving it to the center of the screen and turning it faceup each time the user presses the spacebar.  

Solution 

.data

prompt:     .asciiz     “Difficulty to use? (1-6): ”

# class Card

card:   .struct

value:  .word   0

posx:   .word   0

posy:   .word   0

face:   .byte   0

hidden: .byte   0

.byte   0

.byte   0

.data

.align  4

cards:  .word   0

names:  .ascii  ” A 2 3 4 5 6 7 8 910 J Q K”

figures: .byte  3,4,5,6

tempup: .byte   218,196,196,196,196,196,191,0

.byte   179,032,032,032,032,032,179,0

.byte   192,196,196,196,196,196,217,0

tempdn: .byte   201,205,205,205,205,205,187,0

.byte   186,032,032,032,032,032,186,0

.byte   200,205,205,205,205,205,188,0

decks:  .byte   1,2,3,5,7,9

ncards: .word   0

.extern _lfsr,4

.text

.globl      main

main:

li      $t0,1           # initialize lfsr

sw      $t0,_lfsr($gp)

ask:

addi  $a0,$0,’\f        # clear the screen

syscall     $print_char

la          $a0,prompt      # print prompt

syscall     $print_string

syscall     $read_int         # read difficulty

beqz    $v0,ask         # repeat while answer <1 and >6

sltiu   $t0,$v0,7

beqz  $t0,ask

move    $s2,$v0         # save difficulty in $s2

la      $t0,decks

add     $t0,$t0,$v0

lb      $t0,-1($t0)     # get number of decks to use

li      $t1,52          # multiply number of decks by 52

mult    $t0,$t1

mflo    $s0             # save number of cards in s0

la      $t0,ncards

sw      $s0,($t0)       # save number of cards in variable

sll     $a0,$s0,2       # multiply number of cards times the size of a pointer (4)

syscall $malloc         # allocate memory for array

la      $t0,cards

sw      $v0,($t0)       # save pointer to array in the cards variable

move    $s1,$v0         # save pointer in $s1

li      $s3,0

create:

jal     card.new        # create new card

sw      $s3,card.value($v0) # save card value

addi    $s3,$s3,1

li      $t0,52

blt     $s3,$t0,1f      # if the value counter >=52, restart to zero

li      $s3,0

1:

sw      $v0,($s1)       # save pointer in array

addi    $s1,$s1,4       # advance position in card array

addi    $s0,$s0,-1      # decrement number of cards to generate

bnez    $s0,create

la      $t0,cards

lw      $a0,($t0)

li      $a1,2

sll     $a1,$a1,$s2     # calculate N = 2<<n

jal     shuffle         # shuffle cards

la      $t0,cards

lw      $s0,($t0)       # load pointer to array of cards in s0

la      $t0,ncards

lw      $s1,($t0)       # load number of cards from variable

play:

lw      $t0,($s0)       # load first card pointer from the array

sb      $0,card.hidden($t0) # set as not hidden

addi  $a0,$0,’\f        # clear the screen

syscall     $print_char

move    $a0,$s0

move    $a1,$s1

jal     deck.draw       # draw the deck

li      $t0,32

2:  syscall $read_char      # wait for a spacebar

bne     $v0,$t0,2b

lw      $a0,($s0)       # load first card pointer from the array

sb      $0,card.hidden($a0) # set as not hidden

li      $t0,1

sb      $t0,card.face($a0) # set as face up

li      $t0,36              # show at the middle of console

sw      $t0,card.posx($a0)

li      $t0,9

sw      $t0,card.posy($a0)

jal     card.draw

li      $t0,32

3:  syscall $read_char      # wait for a spacebar

bne     $v0,$t0,3b

addi    $s0,$s0,4       # advance position in card array

addi    $s1,$s1,-1      # decrement number of cards played

bnez    $s1,play

syscall $exit           # exit program

nop

###############################################

# deck.draw method

# Input: $a0 = pointer to deck to draw

#        $a1 = number of cards in deck

###############################################

deck.draw:

addi    $sp,$sp,-12

sw      $ra,0($sp)          # save return address

sw      $s0,4($sp)          # save s0

sw      $s1,8($sp)          # save s1

move    $s0,$a0

move    $s1,$a1

beqz    $a1,1f

showdeck:

lw      $a0,($s0)       # load a card pointer from the array

jal     card.draw       # show the card

addi    $s0,$s0,4       # advance position in card array

addi    $s1,$s1,-1      # decrement number of cards to show

bnez    $s1,showdeck

1:  lw      $ra,0($sp)  # recover return address

lw      $s0,4($sp)  # recover s0

lw      $s1,8($sp)  # recover s1

add     $sp,$sp,12

jr      $ra

###############################################

# card.box method

# Input: $a0 = pointer to card

###############################################

card.box:

addi    $sp,$sp,-8

sw      $ra,0($sp)          # save return address

sw      $s0,4($sp)          # save s0

move $s0,$a0                # save a0 in s0

lw  $t0,card.posx($s0)

lw  $t1,card.posy($s0)

li  $t2,0

lb  $t2,card.face($s0)      # load face state

beqz $t2,down

la   $t2,tempup             # load up template

b    b1

down:

la   $t2,tempdn             # load down template

b1:

move $a0,$t0

move $a1,$t1

syscall     $xy                 # move cursor

move $a0,$t2

syscall $print_string       # print template row

addi $t2,$t2,8              # go to next line in template

addi $t1,$t1,1              # go to next line in console

li   $t3,5

1:  move $a0,$t0

move $a1,$t1

syscall     $xy                 # move cursor

move $a0,$t2

syscall $print_string       # print template row

addi $t1,$t1,1              # go to next line in console

addi $t3,$t3,-1

bnez $t3,1b

addi $t2,$t2,8              # go to next line in template

move $a0,$t0

move $a1,$t1

syscall     $xy                 # move cursor

move $a0,$t2

syscall $print_string       # print template row

lw      $ra,0($sp)  # recover return address

lw      $s0,4($sp)  # recover s0

add     $sp,$sp,8

jr $ra

###############################################

# card.draw method

# Input: $a0 = pointer to card

###############################################

card.draw:

addi    $sp,$sp,-8

sw      $ra,0($sp)  # save return address

sw      $s0,4($sp)  # save s0

move $s0,$a0

li  $t0,0

lb  $t0,card.hidden($s0)    # if the card is hidden, so not show

bnez $t0,hide

jal card.box                # draw the card box

li  $t0,0

lb  $t0,card.face($s0)      # load face state

beqz $t0,hide               # if it’s down, do not show value

lw  $t0,card.value($s0)     # get card number

srl $t1,$t0,2               # divide over 4 to get name

sll $t1,$t1,1

andi $t2,$t0,3              # get figure in t2

la  $t3,names               # get name

add $t3,$t3,$t1

lw  $a0,card.posx($s0)      # print card name

add $a0,$a0,4

lw  $a1,card.posy($s0)

add $a1,$a1,1

syscall     $xy                 # move cursor

lb  $a0,0($t3)

syscall $print_char

lb  $a0,1($t3)

syscall $print_char

lw  $a0,card.posx($s0)      # print card figure

add $a0,$a0,3

lw  $a1,card.posy($s0)

add $a1,$a1,3

syscall     $xy                 # move cursor

la  $t3,figures             # get figure

add $t3,$t3,$t2

lb  $a0,0($t3)

syscall $print_char

hide:

lw      $ra,0($sp)  # recover return address

lw      $s0,4($sp)  # recover s0

add     $sp,$sp,8

jr      $ra

###############################################

# card.new method

# Output: $v0 = pointer to new card

###############################################

card.new:

li      $a0,16          # allocate memory for a card

syscall $malloc

move    $a0,$v0         # move allocated pointer to $a0 for card.card

###############################################

# card.card method, constructor of card class

# Input: $a0 = pointer to card

# Output: $v0 = pointer initialized card

###############################################

card.card:

sw  $0,card.value($a0)

sw  $0,card.posx($a0)

sw  $0,card.posy($a0)

sb  $0,card.face($a0)

li  $t0,1

sb  $t0,card.hidden($a0)

move $v0,$a0            # return pointer to card

jr  $ra

###############################################

# shuffle method

# Input: $a0 = pointer to array of card pointers

###############################################

shuffle:

addi    $sp,$sp,-4

sw      $ra,0($sp)  # save return address

1:  jal     lfsr

div     $v0,$a1

mfhi    $t0         # t0 = lfsr() % a1

sll     $t0,$t0,2

add     $t0,$t0,$a0 # calculate &array[t0]

lw      $t2,($t0)   # t2=array[t0]

addi    $a1,$a1,-1  # –a1

sll     $t1,$a1,2

add     $t1,$t1,$a0 # calculate &array[–a1]

lw      $t3,($t1)   # t3 =array[–a1]

sw      $t3,($t0)   # array[t0] =t3

sw      $t2,($t1)   # array[a1] =t2

bgtz    $a1,1b

lw      $ra,0($sp)  # recover return address

add     $sp,$sp,4

jr      $ra

###############################################

# Galois lfsr prng

# Output: $v0 = random number

###############################################

lfsr:

li   $v0,0x0d000001

lw   $t0,_lfsr($gp)      # load current value of lfsr

srl  $t1,$t0,1

andi $t0,$t0,1

beqz $t0,1f

li   $t0,-1

1:  and  $v0,$v0,$t0

xor  $v0,$v0,$t1

sw   $v0,_lfsr($gp)

jr   $ra