New coder help Family Basic

Started by Phosis, November 03, 2021, 08:54:10 am

Previous topic - Next topic

Phosis

Hello everyone. I am trying to work may way through and understand the code of one of the example problems in the Family Basic manual, namely the KNIGHT game. I am just having trouble breaking down and understanding what the different parts of the code are doing.

I know its a bit vague to ask but is anyone able to sort of assist me with this? Ultimately I am trying to modify it to make a chess game, so I guess the most important part is understanding how the movement through the grid works.

Thank you

P

Well how much BASIC do you know? Have you completed the tutorial part of the manual and learned the basics?
I don't have time now but I can look at the code later.

UglyJoe

I'll take a look, too, and post some commented source code.  Between P's analysis and mine hopefully you'll be able to see what it's doing ;D

A chess game will be a bit ambitious, but I think it would be possible (without a "vs CPU" mode) if you use the extra RAM available in Family Basic V3.

Phosis

Hey guys,

Thank you both.

I am just learning BASIC. I figured out how arrays and multi-dimensional arrays work yesterday. I have worked through the tutorials in the book and am now getting to these programs.

theoakwoody

When you finish the game can you share the audio file?

UglyJoe

Here are my comments on the code.  I was hoping to go a bit more in-depth, but haven't had much time so figured I'd post what I have now instead of keeping you waiting.  If you have any questions feel free to ask ;D


// Turn on the BG and define player sprites/colors
10 VIEW:CGEN 3:CGSET 1,1
20 DEF SPRITE 0,(0,0,0,0,0)=CHR$(&HC7)
30 PALETS 0,13,&H16,&H27,2
40 DEF SPRITE 2,(0,0,0,0,0)=CHR$(&HD7)
50 DEF SPRITE 1,(1,0,0,0,0)=CHR$(&HC7)
60 PALETS 1,13,&H16,&H17,4
70 DEF SPRITE 3,(1,0,0,0,0)=CHR$(&HD7)
80 SPRITE ON
// HX an HY arrays hold the X and Y positions for player 1 (0) and player 2 (1)
90 DIM HX(1),HY(1)
// X and Y arrays are defining the valid moves a Knight can make
// B is a two-dimensional array holding the state of our 8x8 board
100 DIM X(7),Y(7),B(7,7)
// Populate possible Knight moves into X and Y arrays
110 X(0)=-1:Y(0)=-2
120 X(1)=-2:Y(1)=-1
130 X(2)=-2:Y(2)= 1
140 X(3)=-1:Y(3)= 2
150 X(4)= 1:Y(4)= 2
160 X(5)= 2:Y(5)= 1
170 X(6)= 2:Y(6)=-1
180 X(7)= 1:Y(7)=-2
// C is controlling whose turn it is (0 or 1)
// init player 1
190 C=0:GOSUB 250
// init player 2
200 C=1:GOSUB 250
// compact way of saying "if c is 1, make c 0, if c is 0, make c 1"
// (or 'set C to the other player')
// this is how the game makes players "take turns"
210 C=1+(C=1)
220 GOSUB 390
230 IF F=-1 THEN 560
240 GOTO 210
// Player initialization
// Start current player at 0,0. "Finished" flag is reset.
250 X=0:Y=0:F=0
// jump to player-input routine
260 GOSUB 440
// player made an invalid move, so make a sound and try again
270 IF F=1 THEN PLAY"T1O3C2":F=0:GOTO 260
// if the player pressed A then we now know it was a valid move, so we're done with this turn
// should return to calls made at 190 or 200 or (usually) 220
280 IF T=8 THEN RETURN
// process d-pad input when choosing initial player locations
// player pressed 'down' on d-pad
// increment Y value but don't let it go beyond the edge of the board (beyond 7)
290 IF S=4 THEN Y=Y+1:IF Y>7 THEN Y=7
// player pressed 'up' on d-pad
// decrement Y value but don't let it go beyond the edge of the board (beyond 0)
300 IF S=8 THEN Y=Y-1:IF Y<0 THEN Y=0
// some obtuse math here to determine whether to increment or decrement X
// S=1 evaluates to -1 (true) if player pressed 'right' on d-pad
// S=1 evaluates to 0 (false) if player did not press 'right' on d-pad
// similar logic for S=2 but with 'left' on d-pad
// so depending on whether left or right was pressed, we'd add or subtract 1 from X
// (or we'd add or subtract 0 if neither was pressed)
310 X=X+(S=1)-(S=2)
// bounds checking (keeps X between 0 and 7)
320 X=-X*(X>0)+(X>7)
// player's move won't really be done until they press 'A' on a valid square, so update sprite and wait for input again
330 GOTO 260
// start of a loop, but we usually start at 390 (via 220)
// this loop checks to see if the player has any valid moves to make
340 GOSUB 440:F=0
350 IF T=8 THEN RETURN
// if user pressed a button other than 'A', treat it as if they pressed 'down' on the d-pad
360 IF S=0 THEN S=4
// if user pressed 'up' on d-pad, decrement possible-move counter (wrapping around if necessary)
370 IF S=8 THEN N=N-1:IF N<0 THEN N=7
// if user pressed 'down' on d-apd, increment possible-move counter (wrapping around if necessary)
380 IF S=4 THEN N=N+1:IF N>7 THEN N=0
// modify current player's X and Y for current N value within the X and Y arrays
390 X=HX(C)+X(N):Y=HY(C)+Y(N)
// increment F until we've tried all 8 possible valid moves
// (when jumping from 220, F should be 0)
// if we tried them all, set the Finish flag to -1 (game is over!)
400 F=F+1:IF F>8 THEN F=-1:RETURN
// if this valid move would be out of bounds, go to 360
// (which will increment or decrement N so that we try the next possible move)
410 IF X<0 OR X>7 OR Y<0 OR Y>7 THEN 360
// if this valid move puts the player on a square that's alredy been used, go to 360 (to try the next move)
420 IF B(X,Y)=1 THEN 360
// if we made it here then we found that a valid move is available, so
430 GOTO 340
// player-input routine (also 'draw-player-sprite' routine')
// Draw the player's sprite at their current X,Y location
// (the extra numbers here are to compensate for pixel dimensions)
440 SPRITE C,136-16*X,16*Y+47
// read the current players controller input (buttons in T, d-pad in S)
450 T=STRIG(C):S=STICK(C)
// if the user didn't make any input, go back and try again (while loop...)
460 IF (S+T)=0 THEN 450
// if the player didn't press the 'A' button then exit the input routine
470 IF T<>8 THEN 540
// otherwise player pressed the 'A' button
// check if the board location has already been used for the curent X,Y
// if so, set F to 1 and return
480 IF B(X,Y)=1 THEN F=1:RETURN
// otherwise B(X,Y) has not been set, so set it now
490 B(X,Y)=1
// store the curent player's X,Y
500 HX(C)=X:HY(C)=Y
// draw the current player's flag at their current location
510 SPRITE C+2,136-HX(C)*16,16*HY(C)+47
// move cursor to player's current location
520 LOCATE 15-2*HX(C),3+2*HY(C)
// draw an asterisk at the location and play a sound
530 PRINT"*":PLAY"T1O3CDEG"
// end-of-turn routine
// hide the player's sprite
540 SPRITE C
// return to whatever got us here via GOSUB
550 RETURN
// end-of-game routine
560 'END ROUTINE
570 LOCATE 3,20:PLAY"T1O3CDET2O4EGAC"
580 IF C=1 THEN PRINT "BLUE ";
590 IF C=0 THEN PRINT "RED ";
600 PRINT "WIN !!":END