A downloadable game

--------------------------------------------------------------------

 CONNECT 4 - A Classic Game in just 10 lines for MSX 1st generation

--------------------------------------------------------------------

Connect 4 is a well-known classic game where you have to get four disks in the same diagonal, horizontal or vertical line. 

The game starts answering who will be the first to move, if you press 'Y' or 'y', you will play the first, anything else 

makes computer play. Use the left and right arrows to move your disk over the chosen colum and the down arrow to drop it, 

afterwards the program takes a little time to check whether 4 disk-in-line is done, if so, you win, if not, computer thinks 

and checks lines.

Once the game ends up, press 'return' to restart the program.

The game can be played on real computers but it is recommended to take advantage of emulators. The program takes 1 minute 

and half or so to choose its movement. It is not very fast but... it is playable and the first game in 10liners contest on 

its kind. If openmsx is used, you can press F9 key to hasten the program. Another option is to go to the msxpen web page and 

'copy and paste' the code there, this online emulator also allows you to make the code faster.

--------------

 INSTRUCTIONS

--------------

Real machines:  save the cnt4.wav file in a real cassette for using it on your favorite MSX and type RUN"CAS:" plus return

Emulators:      open the cnt4.wav file in BlueMSX/Openmsx/fmsx/RuMSX or whatelse and type RUN"CAS:" plus return

MSXPEN:         Go to https://msxpen.com/ webpage and copy and paste the code inside cnt4.bas file

--------------

 FILES INSIDE

--------------

cnt4.txt This text

cnt4.bas Game saved in ASCII mode (listeable on any text editor)

cnt4.png Picture

cnt4.wav    Audio file program for emulators and real machines

---------------------------

 Author and released year:

--------------------------

José Javier Franco Benítez as current MSXVR user :P

Copyleft 2021

Category: Extrem-256 - MSX1

------------------------------------- 

 Here you find the code explanation:

-------------------------------------

line 10                                                 

    DEFINT A-Z                                          ; Define as intenger all vars which initials go to A till Z

    DIM B(50)                                           ; Define B array which holds all gameboard values. It has more than it is needed, just 42 values are used

    DIM L(7)                                            ; Define L array for upper bounder for every colum

    COLOR 7,1,1                                         ; Swicht color to light blue and black

    SCREEN2,2,0                                         ; Set mode screen

    OPEN"GRP:"AS#1                                      ; Allow to write on graphic mode

    FOR I=0 TO 7                                        ; Retrive text messages from datas

        READ T$(I)

    NEXT

    FOR J=0 TO 1                                        ; Define disk sprites (filled and empty one)

        A$=""

        FOR I=1 TO 32

            READ D

            A$=A$+CHR$(D)

        NEXT    

        SPRITE$(J)=A$

    NEXT

    ON INTERVAL=100 GOSUB 100                           ; Set interruption routine which will be executed every 2 seconds after activating

    DEFUSR=&HB1                                         ; Set BIOS call for waiting for RETURN pressed

    FOR I=5 TO 7                                        ; Set Title and allow you to decide who will start the game 

        PSET(2,I*8-16-120*(I=7))

        PRINT#1,T$(I)

line 20

    NEXT

    FOR I=28 TO 32

        CIRCLE(128,96),I,11

    NEXT

    A$=INPUT$(1)                                        ; Wait for any key pressed

    CLS                                                 ; Clear screen and draw gameboard

    LINE(55,33)-(199,158),4,BF                          

    FOR J=0 TO 5

        FOR I=0 TO 6

            X=I*20+67

            Y=J*20+45

            CIRCLE(X,Y),7,1

            PAINT(X,Y),1,1

        NEXT I,J

    UX=120                                              ; Set variables: UX,uy horizontal valule in pixels for player disk and A is the fourth colum

    UY=14

    A=3

    IF A$<>"Y" AND A$<>"y" THEN                         ; If A$ is any value different form Y or y then computer start playing...

        PSET(56,170)                                    ; ... send text message "LET ME THINK..."

        PRINT#1,T$(3)

        INTERVALON                                      ; Turn on interruption routine

        GOTO50                                          ; go to line 50 and end if

line 30                                                 ; ---------------- PLAYER MOVE -------------------------------------------------------------------

    INTERVAL OFF                                        ; Turn off interruption routine

    PSET(56,170)                                        ; Set text message "MOVE" 

    PRINT#1,T$(4)

    PUTSPRITE0,(UX,UY),11,0                             ; Set initial disk player sprite

    D=STICK(0)                                          ; Arrow keys control

    A=A+(D=7)-(D=3)                                     ; Two decisions: a) if d=7 then a=a-1 b) if d=3 then a=1+1. Choose colum to play

    A=A-(A<0)+(A>6)                                     ; Two decisions: a) if a<0 then a=a+1 b) if a>6 then a=a-1. Horizontal limits police

    UX=A*20+60                                          ; Set UX value needed for 'put sprite' instruction

    IF D<>5 OR L(A)=6 GOTO 30 ELSE                      ; If d=5 and L(A) then dropping piece. A is the chosed colum, L(A)=6 means that colum A is filled...

        PLAY"D"                                         ; ...in other case make movement with little visual effect

        FOR H=0 TO 5-L(A)

        PUTSPRITE0,(UX,UY+H*20),11,0

        FOR R T=0 TO 30                 ; Simple delay

        NEXTRT,H

    PUTSPRITE0,(O,UY),0,0                               ; remove sprite from screen and endif

line 40 

    B((5-L(A))*7+A)=1                                   ; Mark the gameboard array for the player move

    L(A)=L(A)+1                                         ; Increase the upper bounder array

    X=A*20+67                                           ; Set X and Y values for the final disk player position

    Y=(6-L(A))*20+45

    CIRCLE(X,Y),7,11

    PAINT(X,Y),11

    LINE(0,170)-(255,178),1,BF                          ; Erase text area for next message

    P=1                                                 ; Set P=1 (player mark)

    GOSUB80                                             ; call check 4 lines routine to know if player win

    PSET(56,170)

        IF T>0 THEN PRINT#1,T$(0)                       ; if player win, send message "YOU WON"

        A=USR(0)                                        ; Wait for RETURN pressed

        RUN                                             ; Restart the program

    ELSE                                                ; ...else...

        E=0                                             ; Set E as the first colum for thinking computer effect 

        PRINT#1,T$(3)                                   ; Send message "LET ME THINK..."

        INTERVAL ON                                     ; Turn on interruption routine

line 50                                                 ; ---------------- COMPUTER MOVE -----------------------------------------------------------------

    A=INT(RND(-TIME)*6)                                 ; choose colum using Random Basic service from 0 to 6 (seven values; seven colum)

    IF L(A)>5 THEN 50                                   ; if L(A) (upper bounder array) is filled then got to take out another value going to the beginning of the line

    ELSE

        FOR E=0 TO 6                                    ; Go through every colum and check if four line is made by the player, if so, choose that colum to drop the disk 

            Z=-((5-L(E))*7+E)*(L(E)<6)-42*(L(E)>5)      ; Avoid check out of gameboard limits

            P=1                                         ; player mark for the gameboard array

            B(Z)=1

            GOSUB80

            B(Z)=0

            A=-E*(T>0)-A*(T=0)                          ; if not line is made by the player, keep on the random colum at the begining chosed. If line is made, swith colum

        NEXT

        FOR E=0 TO 6                                    ; Go through every colum and check if foru line is made by the computer. It is similar to the previous FOR...NEXT

            Z=-((5-L(E))*7+E)*(L(E)<6)-42*(L(E)>5)

            P=2                                         ; computer mark for the gameboard array

            B(Z)=2

            GOSUB80

            B(Z)=0

            A=-E*(T>0)-A*(T=0)                          ; if line is made by computer, switch colum, in other case keeping the previous one

            G=-(T>0)ORG                                 ; G holds T value for knowing computer victory later

        NEXT

line 60 

    FOR H=0 TO 5-L(A)                                   ; dropping disk effect

        PUTSPRITE0,(A*20+60,UY+H*20),6,0

        PUTSPRITE0,(0,0),0,0

    NEXT

    B((5-L(A))*7+A)=2                                   ; Mark gameboard array for computer move

    X=A*20+67                                           ; Set X value for drawing computer disk

    L(A)=L(A)+1                                         ; Increase upper bounder array

    Y=(6-L(A))*20+45                                    ; Set Y value for drawing computer disk

    PLAY"C"                                             ; Emit simple C note (note DO)

    CIRCLE(X,Y),7,6                                     ; Paint computer disk

    PAINT(X,Y),6                                        ; Fill computer disk

    LINE(0,170)-(255,178),1,BF                          ; Erase text area

    PSET(56,170)                                        ; Put text pointer at 56,170

    A=3                                                 ; Set initial colum at fourth position (colums are numered as 0,1,2,3,4,5,6) 

    IF G>0 THEN PRINT#1,T$(1)                           ; If G>0 (T>0) then print message "YOU LOST"...

        A=USR(0)                                        ; Wait for RETURN pressed

        RUN                                             ; restart and end if

line 70 

PUT SPRITE 0,(0,0),0,0                 ; Remove sprites from screen

PUT SPRITE 1,(0,0),0,1

F=F+2                         ; Increase move counter

IF F<42 THEN 30 ELSE                 ; If F=42, all holes are filled, therefore It is draw

PRINT#1,T$(2)                     ; Send message "IT IS DRAW,NOBODY WON"

A=USR(0)                         ; Wait for RETURN pressed

RUN                             ; Restart program

line 80                         ; ---------------- CHECK LINES -------------------------------------------------------------------

T=0                             ; T holds number of 4 disk-in-line that were done

FOR H=0 TO 1                     ; H=0 for checking vertical lines, H=1 for checking horizontal lines

FOR I=0 TO 5-(H=0)                     ; Main loop for checking horizontal and vertical lines

S=1                             ; S offset position in every line

K=0                             ; Partial line control, start at 0 disk in the line

FOR J=0 TO 5-(H=1)                     ; Sub-main loop for checking horizontal and vertical lines

M=(B(J+I*7)=P)*S*(H=1)                 ; Transform phisical 4 disks to concept 4 bits

  +(B(J*7+I)=P)*S*(H=0)

K=-(K+M)*(M>0)                     ; Partial line control

S=S*2                         ; Increase bit (8=1000,4=0100,2=0010,1=0001), if M=15 then 4 disk-in-line was made

FOR R=0 TO 2+H                     ; Checking if 4 disk-in-line was made 

T=T-(K=2^R*15)

NEXTR,J,I,H

FOR I=0 TO 3                     ; Algorithm for checking diagonal lines. Choose table (*see final note)

FOR J=0 TO 2                     ; Choose diagonal line

K=0

FOR V=I+3 TO I+21 STEP 6                 ; Adjust initial value for up-right to down-left orientation

K=K-(B(J*7+V)=P)                     ; Partial disk control

NEXT

line 90 

T=T-(K=4)                         ; if K=4 then T=T+1 (add one filled line more)

K=0

FOR V=I TO I+24 STEP 8                 ; Adjust initial value for up-left to down-rigth orientation

K=K-(B(J*7+V)=P)                     ; Partial disk control

NEXT

T=T-(K=4)                         ; if K=4 then T=T+1 (add one filled line more)

NEXTJ,I

RETURN

line 100 

PUT SPRITE 0,(E*20+60,UY),9,1             ; Thinking effect. Rotate disks by the colums

PUT SPRITE 1,(A*20+60,UY),6,0

RETURN

-------

 DATAS

------- 

Datas are put on left lines (datas just hold text messages and sprites values)

DATA"YOU WON","YOU LOST","IT IS DRAW,NOBODY WON","LET ME THINK...",MOVE,"CONNECT 4 - 10LINERS CONTEST'21","by Javier Franco","DO YOU WANT RUN TO START(Y/y)?"

DATA3,15,31,63,127,127,255,255,255,255,127,127,63,31,15,3,192,240,248,252,254,254,255,255,255,255,254,254,252,248,240,192,3,12,16,32,64,64,128,128,128,128,64,64,32,16,12,3

DATA192,48,8,4,2,2,1,1,1,1,2,2,4,8,48,1

-------------

 *FINAL NOTE

-------------

The gist to check diagonal lines is based on going through all elements according to the next tables using for-next loops:

           3           4           5           6

        9 10       10 11       11 12       12 13

    15 16 17    16 17 18    17 18 19    18 19 20

 21 22 23    22 23 24    23 24 25    24 25 26

 28 29       29 30       30 31       31 32

 35          26          37          28  

  0           1           2           3

  7  8        8  9        9 10       10 11

 14 15 16    15 16 17    16 17 18    17 18 19

    22 23 24    23 24 25    24 25 26    25 26 27

       30 31       31 32       32 33       33 34

  38          39          40          41

Keep in mind that the B() array (gameboard array) is organized as:

  0  1  2  3  4  5  6

  7  8  9 10 11 12 13

 14 15 16 17 18 19 20

 21 22 23 24 25 26 27 

 28 29 30 31 32 33 34

 35 36 37 38 39 40 41

Download

Download
cnt4.wav 1 MB
Download
cnt4.bas 2 kB
Download
cnt4.txt 13 kB

Comments

Log in with itch.io to leave a comment.

congratulations, the line check algorithm is very difficult

felicidades, el algoritmo de comprobación de líneas es muy dificil