Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Connect 4
#1
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 Smile

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
Reply
#2
Statistics show that, Player 1, has the highest success rate over Player 2. Perhaps a routine to randomly select the first player?

Other than that, a very nice job! Well done!!
Logic is the beginning of wisdom.
Reply
#3
(01-11-2026, 08:40 AM)johnno56 Wrote: Statistics show that, Player 1, has the highest success rate over Player 2. Perhaps a routine to randomly select the first player?

Other than that, a very nice job! Well done!!

Try another version, this one is SUPER EASY, guarantee  Big Grin 

Code:
'===========================================
'
' CONNECT 4 - EASY 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: board(row, col)
visible board = dim(ROWS, COLS)
visible turn

pln "CONNECT FOUR - Human (X) vs Computer (O)"
InitBoard()

turn = 1  ' Human 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 = 2
            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 100
        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 = 1
    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

' 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

function AITurn()
    col = 1
    action = ""

    ' 1. Can AI win?
    col = FindWinningMove(2)
    if col >= 0 then
        action = "..."
    else
        ' 2. Block human win?
        col = FindWinningMove(1)  ' same function: check if human would win
        if col >= 0 then
            action = "  Computer blocks your win!"
        else
            ' 3. Random move
            do
                col = int(rnd() * COLS)
            until IsValidMove(col)
        endif
    endif

    write action
    PlaceChip(2, col)
    pln " Computer in column "+ (col + 1)
    wait 2000
endfunc
Reply
#4
Hey to all..
well this is fine but is kind of unread able to me
and why is this a console app Big Grin


Attached Files Thumbnail(s)
   
Reply
#5
(01-11-2026, 09:45 AM)aurel Wrote: Hey to all..
well this is fine but is kind of unread able to me
and why is this a console app Big Grin

It's just a simple console mode. It reminds me of reading Basic Computer Games by David Ahl back in the 70s. No graphics, just text-based, typing code in BASIC...perhaps my grandson will be able to convert it with beautiful GUI  Big Grin
Reply
#6
grandson,,,,???
wow
Reply
#7
Very good - thanks for sharing 1micha.elok...
Reply
#8
Well done!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)