01-11-2026, 05:24 AM
(This post was last modified: 01-11-2026, 08:55 AM by 1micha.elok.)
CONNECT 4
- Be the first player to get 4 of your chips in a row horizontally, vertically, or diagonally
- Connect 4 was invented by Howard Wexler and Ned Strongin in 1974
- It's a text based game, no graphics, no GUI, just an old classic terminal style game
Note :
Behold "asm...endasm" is in the program
- Be the first player to get 4 of your chips in a row horizontally, vertically, or diagonally
- Connect 4 was invented by Howard Wexler and Ned Strongin in 1974
- It's a text based game, no graphics, no GUI, just an old classic terminal style game
Note :
Behold "asm...endasm" is in the program

Code:
'===========================================
'
' CONNECT 4 - ALMOST UNBEATABLE VERSION
' - Be the first player to get
' 4 of your chips in a row
' horizontally, vertically, or diagonally
' - Connect 4 was invented by
' Howard Wexler and Ned Strongin
' in 1974
'
' Note :
' Behold "asm...endasm" is in the program :)
'
'============================================
' constant
constant ROWS = 6 ' indices 0 to 5
constant COLS = 7 ' indices 0 to 6
constant CONNECT = 4
' Global board(row, col)
visible board = dim(ROWS, COLS)
visible turn
pln "CONNECT FOUR - Human (X) vs Computer (O)"
InitBoard()
turn = 0 ' Computer starts first
printBoard()
'-----------
' MAIN loop
'-----------
do
if turn = 1 then
' Human's turn
pln
write "Your move - Enter column (1 to "+ COLS+ "): "; cmd = rln(1,TYPE_NUMBER)
colInput = cmd
if colInput >= 1 and colInput <= COLS then
col0 = colInput - 1
if IsValidMove(col0) then
PlaceChip(1, col0)
pln "You placed in column "+ colInput
wait 2000
printBoard()
turn = 0
else
pln "Column is full! Try another."
endif
else
pln "Invalid column. Enter 1 to "+ COLS
endif
else
' Computer's turn
write "Computer is thinking..."
wait 300
AITurn()
printBoard()
turn = 1
endif
' Check win/draw
if CheckWinInColumn(1, -1) then
pln "You win! Congratulations!"
' mimic a gosub to label AskReplay
asm
move @0 AskReplay:
call @0
endasm
elseif CheckWinInColumn(2, -1) then
pln "Computer wins! Better luck next time."
' mimic a gosub to label AskReplay
asm
move @0 AskReplay:
call @0
endasm
elseif BoardFull() then
pln "It's a draw!"
' mimic a gosub to label AskReplay
asm
move @0 AskReplay:
call @0
endasm
endif
loop
'sub-routine
asm
AskReplay:
endasm
do
write "Play again? (Y/N)"; again = rln(1,TYPE_STRING)
pln
until upper(again)="Y" or upper(again)="N"
if upper(again) = "Y" then
again = "n"
InitBoard()
turn = 0 ' Computer starts again
printBoard()
' return to whereever we were called from.
asm
ret
endasm
else
pln "Thanks for playing! Goodbye!"
pln
system("pause")
end
endif
' -----------------------------
' functions
' -----------------------------
function InitBoard()
for r = 0 to ROWS - 1
for c = 0 to COLS - 1
board[r][c] = 0
next
next
endfunc
function printBoard()
pln
pln
for r = 0 to ROWS - 1
for c = 0 to COLS - 1
chip = " "
if board[r][c] = 1 then chip = "X"
if board[r][c] = 2 then chip = "O"
write "["+ chip+ "]"
next
pln
next
for c = 0 to COLS - 1
write " "+ (c + 1) + " "
next
pln
endfunc
function IsValidMove (col)
return (board[0][col] = 0)
endfunc
function PlaceChip (player, col)
for r = ROWS - 1 to 0 step -1
if board[r][col] = 0 then
board[r][col] = player
break
endif
next
endfunc
' Returns the row where a chip would land in column 'col'
function GetDropRow(col)
for r = ROWS - 1 to 0 step -1
if board[r][col] = 0 then
return r
endif
next
return -1
endfunc
' col = -1 ? full board check; else simulate move in col
function CheckWinInColumn (player, col)
if col = -1 then
for r = 0 to ROWS - 1
for c = 0 to COLS - 1
if board[r][c] = player then
if CheckPattern(player, r, c) then
return 1
break
endif
endif
next
next
return 0
endif
if not IsValidMove(col) then
return 0
endif
dropRow = -1
for r = ROWS - 1 to 0 step -1
if board[r][col] = 0 then
dropRow = r
break
endif
next
board[dropRow][col] = player
winNow = CheckPattern(player, dropRow, col)
board[dropRow][col] = 0
return winNow
endfunc
function CheckPattern (player, r, c)
ok = 0
' Horizontal
if c <= COLS - CONNECT then
match = -1
for k = 0 to CONNECT - 1
if board[r][c + k] <> player then match = 0
next
if match then ok = -1
endif
' Vertical
if r <= ROWS - CONNECT then
match = -1
for k = 0 to CONNECT - 1
if board[r + k][c] <> player then match = 0
next
if match then ok = -1
endif
' Diagonal \
if r <= ROWS - CONNECT and c <= COLS - CONNECT then
match = -1
for k = 0 to CONNECT - 1
if board[r + k][c + k] <> player then match = 0
next
if match then ok = -1
endif
' Diagonal /
if r >= CONNECT - 1 and c <= COLS - CONNECT then
match = -1
for k = 0 to CONNECT - 1
if board[r - k][c + k] <> player then match = 0
next
if match then ok = -1
endif
return ok
endfunc
function BoardFull ()
full = 1
for c = 0 to COLS - 1
if board[0][c] = 0 then
full = 0
break
endif
next
return full
endfunc
' Returns winning column for 'player', or -1 if none
function FindWinningMove (player)
for c = 0 to COLS - 1
if IsValidMove(c) then
if CheckWinInColumn(player, c) then
return c
endif
endif
next
return -1
endfunc
' Evaluates the board from the perspective of 'player'
function EvaluateBoard(player)
opp = 3 - player ' opponent: 1<->2
score = 0
me2 = 0 ; me3 = 0
opp2 = 0 ; opp3 = 0
' --- Horizontal ---
for r = 0 to ROWS - 1
for c = 0 to COLS - CONNECT
me = 0 ; opponent = 0
for k = 0 to CONNECT - 1
cell = board[r][c + k]
if cell = player then me = me + 1
elseif cell = opp then opponent = opponent + 1
next
if opponent = 0 then
if me = 2 then me2 = me2 + 1
if me = 3 then me3 = me3 + 1
endif
if me = 0 then
if opponent = 2 then opp2 = opp2 + 1
if opponent = 3 then opp3 = opp3 + 1
endif
next
next
' --- Vertical ---
for c = 0 to COLS - 1
for r = 0 to ROWS - CONNECT
me = 0 ; opponent = 0
for k = 0 to CONNECT - 1
cell = board[r + k][c]
if cell = player then me = me + 1
elseif cell = opp then opponent = opponent + 1
next
if opponent = 0 then
if me = 2 then me2 = me2 + 1
if me = 3 then me3 = me3 + 1
endif
if me = 0 then
if opponent = 2 then opp2 = opp2 + 1
if opponent = 3 then opp3 = opp3 + 1
endif
next
next
' --- Diagonal \ ---
for r = 0 to ROWS - CONNECT
for c = 0 to COLS - CONNECT
me = 0 ; opponent = 0
for k = 0 to CONNECT - 1
cell = board[r + k][c + k]
if cell = player then me = me + 1
elseif cell = opp then opponent = opponent + 1
next
if opponent = 0 then
if me = 2 then me2 = me2 + 1
if me = 3 then me3 = me3 + 1
endif
if me = 0 then
if opponent = 2 then opp2 = opp2 + 1
if opponent = 3 then opp3 = opp3 + 1
endif
next
next
' --- Diagonal / ---
for r = CONNECT - 1 to ROWS - 1
for c = 0 to COLS - CONNECT
me = 0 ; opponent = 0
for k = 0 to CONNECT - 1
cell = board[r - k][c + k]
if cell = player then me = me + 1
elseif cell = opp then opponent = opponent + 1
next
if opponent = 0 then
if me = 2 then me2 = me2 + 1
if me = 3 then me3 = me3 + 1
endif
if me = 0 then
if opponent = 2 then opp2 = opp2 + 1
if opponent = 3 then opp3 = opp3 + 1
endif
next
next
' Weighted score: prioritize 3-in-a-row heavily
score = (me3 * 100) + (me2 * 10) - (opp3 * 100) - (opp2 * 10)
return score
endfunc
' Improved AI turn
function AITurn()
col = -1
action = ""
' 1. Can computer win right now?
col = FindWinningMove(2)
if col >= 0 then
action = " (wins!)"
asm
jmp place_move:
endasm
endif
' 2. Must block human's immediate win?
col = FindWinningMove(1)
if col >= 0 then
action = " (blocks you!)"
asm
jmp place_move:
endasm
endif
' 3. Take center column (3) if available — strongest opening
if IsValidMove(3) then
col = 3
action = " (takes center)"
asm
jmp place_move:
endasm
endif
' 4. Evaluate all valid moves and pick best one
bestScore = -999999
bestCol = -1
for c = 0 to COLS - 1
if IsValidMove(c) then
r = GetDropRow(c)
board[r][c] = 2 ' simulate AI move
score = EvaluateBoard(2)
board[r][c] = 0 ' undo
if score > bestScore then
bestScore = score
bestCol = c
endif
endif
next
if bestCol >= 0 then
col = bestCol
action = " (strategic)"
else
'random (should never happen)
do
col = int(rnd() * COLS)
until IsValidMove(col)
action = " (fallback)"
endif
asm
place_move:
endasm
PlaceChip(2, col)
pln " Computer in column "+ (col + 1) + action
wait 1000
endfunc

