QB64 Phoenix Edition
Checker Board - Checker Board Layout with Two Checkers and Mapping Routine. - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: TheBOB (https://qb64phoenix.com/forum/forumdisplay.php?fid=27)
+---- Thread: Checker Board - Checker Board Layout with Two Checkers and Mapping Routine. (/showthread.php?tid=239)



Checker Board - Checker Board Layout with Two Checkers and Mapping Routine. - Pete - 04-27-2022

Checkerboard.bas by Bob Seguin.
[Image: Screenshot-582.png]
Description: Checker Board with two playing pieces. Read the code in the accompanying Mapping.bas utility below to see how it gets built. The pieces are just graphic characters, they cannot be moved.

Code: (Select All)
'----------------------------------------------------------------------------
'
'   AN INTRODUCTION TO GAME MAPPING (program example - freeware)
'  (See MAPPING.BAS for mapping tutorial)
'   Copyright (2000) by Bob Seguin
'
'----------------------------------------------------------------------------

_TITLE "Checkerboard.bas by Bob Seguin"

DEFINT A-Z

DECLARE SUB BOARD ()
DECLARE SUB DrawMAN (x, y, Colr)

DIM SHARED CheckerBOARD(1 TO 8, 1 TO 8)

DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1

FOR Row = 1 TO 8
    FOR Col = 1 TO 8
        READ CheckerBOARD(Row, Col)
    NEXT Col
NEXT Row

SCREEN 12

OUT &H3C8, 0 'Color 0 set to a dark green for background
OUT &H3C9, 0 'so that it can be printed on without creating
OUT &H3C9, 30 'black boxes
OUT &H3C9, 0

OUT &H3C8, 1 'Color 1 set to a black since 0 has been changed
OUT &H3C9, 0
OUT &H3C9, 0
OUT &H3C9, 0

OUT &H3C8, 4 'Color 4 set to a brighter red
OUT &H3C9, 63
OUT &H3C9, 0
OUT &H3C9, 0

BOARD 'Call to sub program to draw checkerboard

RANDOMIZE TIMER 'Assure that each game will be different

'Establish random location for blue game piece making sure it is not on
'the starting square of the white game piece (8, 8). In most cases it won't
'be, so this loop will only iterate once.  As long as one of the coordinates
'isn't 8, it's legal, hence the "OR".

DO
    BlueMANRow = INT(RND * 8) + 1
    BlueMANCol = INT(RND * 8) + 1
LOOP UNTIL BlueMANRow <> 8 OR BlueMANCol <> 8

'Adjust map array accordingly
CheckerBOARD(BlueMANRow, BlueMANCol) = CheckerBOARD(BlueMANRow, BlueMANCol) + 10

'Establish x/y coordinates for blue game piece
BlueMANx = BlueMANCol * 50 + 98 '98 represents left square center - 50
BlueMANy = BlueMANRow * 50 + 15 '15 represents top square center - 50

'Call sub program that draws/erases game pieces
DrawMAN BlueMANx, BlueMANy, 9

'Repeat for white game piece, except starting row/column are fixed: 8, 8
WhiteMANRow = 8
WhiteMANCol = 8

'We know the square is 8/8, therefore red (1) and the white player 20, so...
CheckerBOARD(8, 8) = 21

WhiteMANx = 8 * 50 + 98
WhiteMANy = 8 * 50 + 15

DrawMAN WhiteMANx, WhiteMANy, 15

DO
    DO
        Key$ = INKEY$
    LOOP UNTIL Key$ <> ""
    RowINCREMENT = 0: ColINCREMENT = 0
    SELECT CASE Key$
        CASE CHR$(0) + "H" 'Up
            IF WhiteMANRow > 1 THEN RowINCREMENT = -1 ELSE RowINCREMENT = 0
        CASE CHR$(0) + "P" 'Down
            IF WhiteMANRow < 8 THEN RowINCREMENT = 1 ELSE RowINCREMENT = 0
        CASE CHR$(0) + "K" 'Left
            IF WhiteMANCol > 1 THEN ColINCREMENT = -1 ELSE ColINCREMENT = 0
        CASE CHR$(0) + "M" 'Right
            IF WhiteMANCol < 8 THEN ColINCREMENT = 1 ELSE ColINCREMENT = 0
        CASE CHR$(27)
            SYSTEM
    END SELECT

    'Test for presence of blue game piece at proposed move location. Since
    'the blue game piece is the only object we can possible encounter, I've
    'simply used > 1 as a test.  Other possiblities would require a more
    'complex test.
    IF CheckerBOARD(WhiteMANRow + RowINCREMENT, WhiteMANCol + ColINCREMENT) > 1 THEN
        RowINCREMENT = 0
        ColINCREMENT = 0
    END IF

    'Here is an added wrinkle. If it is not possible to move in certain
    'situations, why bother changing anything, -all you'll succeed in
    'doing is cause your game piece to flutter on the spot. Hence, we
    'enclose the next section in an IF block. To see the difference it
    'makes, REM out the following IF line and the END IF at the bottom,
    'then press F5 and hold down any of the arrow keys:
    IF RowINCREMENT <> 0 OR ColINCREMENT <> 0 THEN '<---REM out to test

        'Decrement map array at old location
        CheckerBOARD(WhiteMANRow, WhiteMANCol) = CheckerBOARD(WhiteMANRow, WhiteMANCol) - 20


        'Erase white game piece at old location, using the value of the map array
        'at those row/col coordinates to establish background color. Since there
        'couldn't have been anything on that square but the white game piece,
        'it's value after the previous line of code will be either 1:red or
        '0:black. (Incidentally, I'm using COLOR 1 for black; see the OUT
        'statements at the start of this program for why).
        IF CheckerBOARD(WhiteMANRow, WhiteMANCol) = 1 THEN Colr = 4 ELSE Colr = 1
        DrawMAN WhiteMANx, WhiteMANy, Colr 'Draws solid circle in background color

        'Establish new row/column, x/y coordinates based on increment values
        WhiteMANRow = WhiteMANRow + RowINCREMENT
        WhiteMANCol = WhiteMANCol + ColINCREMENT
        WhiteMANy = WhiteMANy + RowINCREMENT * 50
        WhiteMANx = WhiteMANx + ColINCREMENT * 50

        'Update map array accordingly
        CheckerBOARD(WhiteMANRow, WhiteMANCol) = CheckerBOARD(WhiteMANRow, WhiteMANCol) + 20
   
        'Draw white game piece at new coordinates
        DrawMAN WhiteMANx, WhiteMANy, 15
   
    END IF '<----REM out to test

LOOP

END

'NOTE: In this simple little program, I could have taken a few short cuts,
'      such as testing for the edge of the board and for the blue game piece
'      at the same time, etc..  It is important, however, that you learn to
'      think of these things separately, since most games involve much more
'      complex circumstances and testing. A chess game, for example, would
'      require establishing the computer's next move based on the position
'      of every piece on the board (values in the array).
'
'      Incidentally, -what values would YOU assign to all 32 chess
'      pieces?
'
'      Bob Seguin
'
'-----------------------------------------------------------------------------

SUB BOARD

    'Sub program draws checkerboard
    '----------------------------------------------------------------------------

    LINE (10, 10)-(629, 469), 8, B
    LINE (7, 7)-(633, 473), 8, B
    LINE (118, 35)-(527, 444), 8, BF
    LINE (118, 35)-(527, 444), 1, B
    FOR x = 123 TO 473 STEP 50
        Col = Col + 1
        FOR y = 40 TO 390 STEP 50
            Row = Row + 1
            LINE (x, y)-(x + 50, y + 50), 14, B
            IF (Col + Row) MOD 2 THEN Colr = 1: ELSE Colr = 4
            PAINT (x + 12, y + 12), Colr, 14
        NEXT y
    NEXT x
    COLOR 8
    LOCATE 30, 31: PRINT " PRESS [ESC] TO QUIT ";

    '-----------------------------------------------------------------------------
END SUB

SUB DrawMAN (x, y, Colr)

    'Sub program draws filled circle at coordinates x/y and in color Colr
    '-----------------------------------------------------------------------------

    WAIT &H3DA, 8
    WAIT &H3DA, 8, 8 'Wait for completed screen retrace to avoid flicker

    CIRCLE (x, y), 20, Colr
    PAINT (x, y), Colr

    '-----------------------------------------------------------------------------

END SUB



Mapping.bas

Code: (Select All)
'----------------------------------------------------------------------------
'
'   AN INTRODUCTION TO GAME MAPPING (tutorial - freeware)
'   Copyright (2000) by Bob Seguin
'
'
'----------------------------------------------------------------------------
DEFINT A-Z

_TITLE "Mapping by Bob Seguin"

'FOR OPENERS...
'Let's start with a simple game example, -a checkerboard type game.
'What we want to do is figure some way to represent this game board in
'a numerical form, such that we can determine at any time and at any
'location, the exact status at that location.  In more complex games
'you might wish to know: Did I just run into a wall or enter a building?
'Is a good guy or bad guy at this location?  If there is someone here,
'is he carrying a weapon, and if so, what kind of weapon?  What is his
'strength and skill level, etc..

'But, for now, let's stick with our simple checkerboard:
'To begin with, we create a two-dimensional array that represents a
'checkerboard: 8 by 8 elements representing the 8 by 8 checkerboard pattern.
'(It is automatically an integer array because of DEFINT A-Z at the top
'of the program, but if you don't use DEFINT A-Z then add AS INTEGER).
DIM SHARED CheckerBOARD(1 TO 8, 1 TO 8)

'Next, we initialize the array using DATA and READ statements, so that
'every red square is equal to 1 and every black square is equal to 0
'in the array representation.

DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1
DATA 1,0,1,0,1,0,1,0
DATA 0,1,0,1,0,1,0,1

'You'll notice that even the DATA looks like a checkerboard.  Well that is
'the value of a two-dimensional array map, it can be used to represent a
'physical space using logically associated, numerical values.

'Next we READ the DATA into the array...
FOR Row = 1 TO 8
    FOR Col = 1 TO 8
        READ CheckerBOARD(Row, Col)
    NEXT Col
NEXT Row

'In the above reading loop, we have to keep in mind that the DATA will be
'read in the same order as it appears in the program, first row first, then
'the second row, etc..  So we do "Row" as the outside loop and "Col" (column)
'as the inside loop: Row 1,-Col 1, 2, 3, 4, etc..  Row 2,-Col 1, 2, 3, 4,
'etc.. Take a second to see the logic of this reading loop.

'If you look at the DATA, you'll see that the bottom-right square is a 1
'(red). If you print CheckerBOARD(8, 8) you should get a 1, now.

'PRINT CheckerBOARD(8, 8)  'The output of this will be a 1.
'PRINT CheckerBOARD(1, 2)  'First row, second column; output is 0 (black).

'SO NOW WHAT?
'Let's imagine that you have two single game pieces.  We give a blue
'piece a value of 10 and a white piece a value of 20.  Whenever a piece is
'moved to a square, that square's value in the array is incremented by
'the value of the piece moved to it.  Whenever a piece moves OFF a square,
'the square's value is decremented by the piece's value. If I told you that
'at some point in the game, CheckerBOARD(Row, Col) = 21, what information
'would you have?

'I'm sure you got it, but if not, check SUB Answer.

'GAMEPLAY
'During game play, there are two positions to be maintained for each game
'piece, whether it's the good guy or the bad guy. The first is it's x/y
'coordinates for purposes of drawing or erasing its image (usually PUT
'statements).  The second is its location in the array.

'Let's say that our checkerboard on the screen is made up of squares 50 by
'50 pixels, -total image 400 by 400.  Every time we increment the x of a
'piece by 50 pixels, for example (move right), we increment its column
'position in the array by 1.  Whenever we draw the image at a new location,
'we also increment its new position in the array by its value.  Conversely,
'whenever we erase its visual image from a previous location, we also
'decrement the corresponding value in the array.

'It is in this way that we can "test" for factors which affect the play of
'the game by simply accessing the array whenever a piece moves to that
'particular Row/Column.  If for example we have placed (at random) a land
'mine on CheckerBOARD(3, 7) and a piece moves there,... BOOOOOOMMMMM!!!.
'The value of the land mine can be anything, as long as we know what the
'number means.  For example, if a land mine is worth 100, then as long as
'the value of the square is >= 100, we know there's a mine there.  It's fun
'to work out values that tell us all there is to know about a square.  You
'can use MOD, integer division (\), etc. for testing purposes, giving you
'multiple circumstances expressed as a single value.


'GETTING STARTED
'Start simple, as with the checkerboard example and two game pieces.  Locate
'one game piece at random. RANDOMIZE TIMER assures a different game each time:
'RANDOMIZE TIMER
'BlueMANRow = FIX(RND * 8) + 1 'See FIX in the Help/Index if you don't
'BlueMANCol = FIX(RND * 8) + 1 'understand its use.
'CheckerBOARD(BlueMANRow, BlueMANCol) = CheckerBOARD(BlueMANRow, BlueMANCol) + 10

'Notice that we did not merely assign the value of the blue game piece to the
'square, -a common error.  Instead, we said that WHATEVER the current value
'of the square, we want it increased by 10.  So if the square was worth 1, it
'is now worth 11.  If it was worth 0, it is now worth 10.  If it was a red
'square with a land mine on it, it is now worth 111.

'Use the arrow keys to move the white game piece.  What follows is a basic
'game-play loop.  All game events and INPUT are inside the outer DO/LOOP:
'DO
'DO
'Ky$ = INKEY$
'LOOP WHILE Ky$ = ""  'Wait for key to be pressed
'RowINCREMENT = 0: ColINCREMENT = 0  'Reset increments to zero
'SELECT CASE Ky$
'    CASE CHR$(0) + "H" 'Up arrow key
'    CASE CHR$(0) + "P" 'Down arrow key
'    CASE CHR$(0) + "K" 'Left arrow key
'    CASE CHR$(0) + "M" 'Right arrow key
'    CASE CHR$(27)      'Escape key (end at any time)
'        SYSTEM
'END SELECT
'LOOP

'ORDER OF EVENTS
'First, we set the increments/decrements based on the key press for
'row/column, checking first to determine if the move is legal:
'Example, up arrow is pressed:
'CASE CHR$(0) + "H" 'Up arrow key
'    IF WhiteMANRow > 1 THEN RowINCREMENT = -1 ELSE RowINCREMENT = 0
'    (Otherwise you might fall off the checkerboard!)

'Second, following the arrow key SELECT CASE, check the value of the square
'you've just chosen to move to. If it's value tells you that the blue game
'piece is on it, reset the INCREMENT values to 0.
'IF CheckerBOARD(WhiteMANRow + RowINCREMENT, WhiteMANCol + ColINCREMENT) > 1 THEN
'    RowINCREMENT = 0
'    ColINCREMENT = 0
'END IF
'In more complex programs, it is in this preceding section that all
'circumstances would be tested for and game play altered accordingly,
'possibly involving sub program calls, etc.. Normally, SELECT CASE would
'be used since a great many values would have to be tested for and SELECT
'CASE is faster for this type of multiple option checking.

'And now, you execute the move (this section of code will not affect
'anything if the increment values haven't been altered).

'1.) Erase game piece image at previous location and decrement the value of
'    CheckerBOARD(WhiteMANRow, WhiteMANCol), accordingly. This is possible
'    because we have not yet altered the row/column, x/y coordinates, so
'    they still represent the game piece's old position.  All we've done at
'    this point is assign values to RowINCREMENT and ColINCREMENT.

'2.) Increment the row/column of the game piece as well as its x/y values:
'    WhiteMANRow = WhiteMANRow + RowINCREMENT
'    WhiteMANCol = WhiteMANCol + ColINCREMENT
'    WhiteMANy = WhiteMANy + RowINCREMENT * 50
'    WhiteMANx = WhiteMANx + ColINCREMENT * 50
'    (It doesn't matter what these increments are, plus or minus, value or
'    no value.  They will automatically provide the correct x/y changes.
'    you might take a moment to see the logic of these statements before
'    moving on).

'3.) Draw game piece at the new location and increment the corresponding
'    element in the array:
'    CheckerBOARD(WhiteMANRow, WhiteMANCol) = CheckerBOARD(WhiteMANRow, WhiteMANCol) + 20

'SUMMING UP...
'The game "Checked.BAS" is the finished version of this game.  You should,
'however, see if you can work it out on your own before looking at that game.
'If you're stumped, by all means, check it out.

'If your little game is successful, you should be able to move your game
'piece anywhere on the board without going off the edge, and whenever you
'encounter the other piece on its randomly-selected square, you should be
'prevented from moving there.

'I've included a checkerboard graphic in SCREEN 12 that you can use to
'get you started.  Copy and paste the BOARD sub to use it (just press F5.
'to see it).  See this sub also for x/y coordinates to get you started
'drawing the simple blue/white game pieces.  Since these images ARE simple,
'you might just use CIRCLE and PAINT statements for erasing and
'drawing images (keep in mind that you can check for the square's color
'when erasing by checking CheckerBOARD(Row, Col). Square_value MOD 10 = 1
'means a red square and square_value MOD 10 = 0 means black, since both
'game pieces as well as a land mine (your option) MOD 10 = 0).
'
'                                     Good luck!
'                                     Bob Seguin
'
'-----------------------------------------------------------------------------

SCREEN 12

OUT &H3C8, 2 'Color 2 set to a darker green for background
OUT &H3C9, 0
OUT &H3C9, 30
OUT &H3C9, 0

OUT &H3C8, 4 'Color 4 set to a brighter red
OUT &H3C9, 63
OUT &H3C9, 0
OUT &H3C9, 0

BOARD 'Call to sub program
a$ = INPUT$(1) 'Wait for a key press
END

DEFSNG A-Z
SUB Answer
    'A red square with a white game piece on it.
END SUB

DEFINT A-Z
SUB BOARD

    PAINT (0, 0), 2
    LINE (7, 7)-(633, 473), 8, B
    LINE (10, 10)-(629, 469), 8, B
    LINE (118, 35)-(527, 444), 8, BF
    LINE (118, 35)-(527, 444), 0, B
    FOR x = 123 TO 473 STEP 50
        Col = Col + 1
        FOR y = 40 TO 390 STEP 50
            Row = Row + 1
            LINE (x, y)-(x + 50, y + 50), 14, B
            IF (Col + Row) MOD 2 THEN Colr = 0 ELSE Colr = 4
            PAINT (x + 12, y + 12), Colr, 14
        NEXT y
    NEXT x

    CIRCLE (148, 65), 20, 15 '148:65 are top row, first column center.
    PAINT (148, 65), 15
    CheckerBOARD(1, 1) = CheckerBOARD(1, 1) + 20
    CIRCLE (198, 65), 20, 9 '198:65 are top row, second column center, etc.
    PAINT (198, 65), 9
    CheckerBOARD(1, 2) = CheckerBOARD(1, 2) + 10

END SUB