LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Grid help

Root / Programming Questions / [.]

BlasticusSaturnCreated:
I'm making a chess game, and the problem I ran into was how I would organize the "grid" of the board. I need a way for it to match up the cursor location with a grid square and from there determine whether or not a piece is there, and if one is, which type. The answer is probably Arrays, but how would I use them to achieve what I want?

You should use an 8x8 array:
DIM BOARD[8,8]
Access each square with BOARD[Y,X] (yes, Y and X are reversed) You could use numbers to store which piece is on each spot, like 0=empty, 1=white pawn, 2=white rook, etc. (or use a string array and use the names of the pieces) And to fill the array with pieces at the start, you should use COPY:
COPY BOARD,@RESET

@RESET
DATA 2,3,4,5,6,4,3,2
DATA 1,1,1,1,1,1,1,1
DATA 0,0,0,0,0,0,0,0
DATA  ...

thanks, that makes sense. if anyone else sees this and think they have another good method, don't hesitate to share it. it'll only widen my understanding.

This is what I recommend doing: These are just things that I have done: Create the board array as a one-dimensional array from 0 to 63 Define the black and white pieces in alternating order, so
  • 0=Empty Space
  • 1=Black Pawn
  • 2=White Pawn
  • 3=Black Knight
  • 4=White Knight
  • 5=Black Bishop
  • 6=White Bishop
  • 7=Black Rook
  • 8=White Rook
  • 9=Black Queen
  • 10=White Queen
  • 11=Black King
  • 12=White King
Then the code would work as so:
DIM BOARD[64]
RESETBOARD

DEF RESETBOARD
 RESTORE @NEWBOARD
 FOR I=0 TO 63
  READ BOARD[I]
 NEXT
 @NEWBOARD
 DATA 7,3,5,11,9,5,3,7
 DATA 1,1,1,1,1,1,1,1
 DATA 0,0,0,0,0,0,0,0
 DATA 0,0,0,0,0,0,0,0
 DATA 0,0,0,0,0,0,0,0
 DATA 0,0,0,0,0,0,0,0
 DATA 2,2,2,2,2,2,2,2
 DATA 8,4,6,12,10,6,4,8
END


'Here are a few extra functions that may help you

'FAST FUNCTION TO CHECK IF AN X,Y POSITION IS WITHIN BOUNDS OF THE BOARD
DEF INBOUNDS(X,Y)
 RETURN X>=0&&Y>=0&&X<8&&Y<8
END

'EXTRACT THE X VALUE OUT OF AN INDEX
DEF GETXINDEX(N)
 IF N>=0&&N<64 THEN RETURN N MOD 8 ELSE RETURN -1
END

'EXTRACT THE Y VALUE OUT OF AN INDEX
DEF GETYINDEX(N)
 IF N>=0&&N<64 THEN RETURN N DIV 8 ELSE RETURN -1
END

'CONVERT FROM X AND Y TO A SINGLE INDEX FROM 0-63
DEF GETINDEX(X,Y)
 IF !INBOUNDS(X,Y) THEN RETURN -1
 RETURN Y*8+X
END

'-1=ERROR
'0=PAWN
'1=KNIGHT
'2=BISHOP
'3=ROOK
'4=QUEEN
'5=KING
DEF GETPIECE(X,Y)
 IF !INBOUNDS(X,Y) THEN RETURN -1
 RETURN (BOARD[Y*8+X]-1) DIV 2
END

'-1=ERROR
'0=BLACK
'1=WHITE
DEF GETCOLOR(X,Y)
 IF !INBOUNDS(X,Y) THEN RETURN -1
 RETURN BOARD[Y*8+X] MOD 2
END
If you are trying to build a chess AI
  • Create a function that can list all the possible positions a piece can be placed with the current board situation
  • Create a scoring system to determine which of those moves will give you the most points
  • Find a minimax algorithm, preferably alpha-beta-pruning, which will use logic to search a certain depth (like 5 moves ahead) in a tree-like structure to rank each path and find the path that has the highest score.
Sorry I got a little carried away, but I hope this helps you at least a little bit.

Why use specifically a 1D array for your approach instead of a 2D [Y,X] one like 12Me did? Here they should be identical aside from how you're indexing them, unless I'm missing something. Also instead of doing this here:
RESTORE @NEWBOARD
FOR I=0 TO 63
 READ BOARD[I]
NEXT
You can do this:
COPY BOARD, @NEWBOARD
EDIT: 12Me already mentioned COPY but oh well.

I chose one dimensional so that positions on the board can be a single number instead of two It's not a big deal, but I find it easier to manage when dealing with more complex functions Like making a function GETBESTMOVE, you can simply make it return one number and avoid the OUT X,Y at the end I just thought it'd be simpler on the user Also that array initialization... Wow! Efficiency That's a neat trick

I thought it might be better to number the pieces like 0=empty, 1=white pawn, -1=black pawn, 2=white rook, -2=black rook, etc. That way you can check the owner of a piece with SGN, and the type of piece with ABS.
DIM BOARD[8,8]
COPY BOARD,@RESET

ABS(BOARD[Y,X]) 'get piece
SGN(BOARD[Y,X]) 'get color
When moving a piece, SWAP is probably the best way:
'check color of piece at new position
VAR COL=SGN(BOARD[NEWY,NEWX])
'if the space doesn't have one of your own pieces
IF COL!=PLAYER THEN
  'if space has one of the other player's pieces, capture it
  IF COL==-PLAYER THEN BOARD[NEWY,NEWX]=0
  'move your piece
  SWAP BOARD[OLDY,OLDX],BOARD[NEWY,NEWX]
ENDIF

I didn't know you could put Data in a function or the copy trick. Very nice. My only addition to the thread would be to make some named pseudo constants so your code is more readable. Something like if piece == KNIGHT_BLACK then is much easier to read when debugging months later than if piece == -24 then. I like the sign idea too, very nice.

I didn't know you could put Data in a function or the copy trick. Very nice. My only addition to the thread would be to make some named pseudo constants so your code is more readable. Something like if piece == KNIGHT_BLACK then is much easier to read when debugging months later than if piece == -24 then. I like the sign idea too, very nice.
Yeah, that would be a good idea. Maybe just KNIGHT for white and -KNIGHT for black would be enough. oh, and if you're going to use the default chess pieces, you should number them in the same order, which is pawn, rook, knight, bishop, queen, king

thanks again for all the help. I didn't expect so many people to pitch in.

So many excellent ideas here!