08-03-2005, 03:24 AM
I am currently working on an Othello (AKA Reversi) game in QBasic. I keep on running into 3 errors in particular, two of them QBasic generated errors (execution stops, QB gives me the error box); the other one is just QB not doing what I want it to most likely due to an error on my part. The two errors that I get are Out of Stack Space (I sometimes get this when the AI is "thinking") (See EDIT 1), and Out of Memory (I never get this during execution, only almost every time I stop the execution--by way of Ctrl-Scroll Lock-- and attempt to edit the code). The second one is extremely annoying because I have to restart QB every time I want to edit code after/while the pogram runs. The third (and most minor) of my errors is that occasionally the AI attempts to do a move that it is not allowed to do. (See EDIT 2) Here is a link to my program: Othello.bas, and the two .bi files it uses: General.bi and Mouse.bi. In order for the program to run, if you are using QB 4.0 or higher, you need to load QB with the /L option. I'm sorry for the complete lack of comments (a bad habbit of mine ). For those who just want to see the code for the AI, here it is:
The temp / 0 is simply to catch the computer at trying to make an illegal move and break the execution. Thanks ahead of time for your help.
EDIT: I made a mistake, the Out of Stack error no longer appers. Also, I updated my program (fixed a few bugs I didn't realize were there, and made it no longer depend on the two header (.bi) files. Here is the updated version: Othello.bas. You no longer need to download the two header files. I also found that the AI isn't as good as I want it to be (it often makes stupid moves). I would welcome any help on the AI also. The logic for the AI is in the sub AIMove.
EDIT 2: The AI no longer tries to make illeagal moves. I updated the code in this post.
Code:
SUB AIMove
DIM Board2(8, 8) AS INTEGER
DIM value(8, 8)
DIM ARow AS INTEGER
DIM AColumn AS INTEGER
DIM ORow AS INTEGER
DIM OColumn AS INTEGER
DIM current(3)
RANDOMIZE (TIMER)
KEY(15) ON
KEY(16) OFF
ERASE value, current
DIM value(8, 8)
DIM current(3)
FOR ORow = 1 TO 8
FOR OColumn = 1 TO 8
Board2(ORow, OColumn) = Board(ORow, OColumn)
NEXT OColumn
NEXT ORow
FOR ARow = 1 TO 8
FOR AColumn = 1 TO 8
IF LeagMove(ARow, AColumn, AIColor) THEN
value(ARow, AColumn) = 100
ListPlace = 0
UpTo = 0
IF ARow = 8 OR ARow = 1 THEN value(ARow, AColumn) = value(ARow, AColumn) + 50
IF AColumn = 8 OR AColumn = 1 THEN value(ARow, AColumn) = value(ARow, AColumn) + 50
FOR i = 1 TO 9
value(ARow, AColumn) = value(ARow, AColumn) + FlipperL(i) / AIColor
NEXT i
OtherMoves = 0
ListPlace = 0
FOR ORow = 1 TO 8
FOR OColumn = 1 TO 8
Board(ORow, OColumn) = Board2(ORow, OColumn)
NEXT OColumn
NEXT ORow
FOR CurColumn = 1 TO 3
FOR CurRow = 1 TO 3
ListPlace = ListPlace + 1
FlipperM(CurRow, CurColumn) = FlipperL(ListPlace)
NEXT CurRow
NEXT CurColumn
FOR CurColumn = -1 TO 1
FOR CurRow = -1 TO 1
IF NOT (CurColumn - 1 AND CurRow - 1) THEN
UpTo = -1
WHILE UpTo < FlipperM(CurRow + 2, CurColumn + 2)
UpTo = UpTo + 1
DIM Mx AS INTEGER
DIM My AS INTEGER
Mx = ARow + CurRow * UpTo
My = AColumn + CurColumn * UpTo
IF Board(Mx, My) <> PColor THEN
Board(Mx, My) = PColor
END IF
WEND
END IF
NEXT CurRow
NEXT CurColumn
FOR ORow = 1 TO 8
FOR OColumn = 1 TO 8
IF LeagMove(ORow, OColumn, 3 - AIColor) THEN
OtherMoves = OtherMoves + 1
IF ORow = 8 OR ORow = 1 THEN OtherMoves = OtherMoves + 15
IF OColumn = 8 OR OColumn = 1 THEN OtherMoves = OtherMoves + 15
END IF
NEXT OColumn
NEXT ORow
value(ARow, AColumn) = value(ARow, AColumn) - OtherMoves
END IF
NEXT AColumn
NEXT ARow
FOR ORow = 1 TO 8
FOR OColumn = 1 TO 8
Board(ORow, OColumn) = Board2(ORow, OColumn)
NEXT OColumn
NEXT ORow
FOR ARow = 1 TO 8
FOR AColumn = 1 TO 8
IF current(3) < 0 THEN current(3) = 1
IF value(ARow, AColumn) = current(3) AND -INT(RND + .5) AND LeagMove(ARow, AColumn, AIColor) THEN
current(1) = ARow
current(2) = AColumn
current(3) = value(ARow, AColumn)
ELSEIF value(ARow, AColumn) > current(3) AND LeagMove(ARow, AColumn, AIColor) THEN
current(1) = ARow
current(2) = AColumn
current(3) = value(ARow, AColumn)
END IF
NEXT AColumn
NEXT ARow
Row = current(1)
Column = current(2)
ik$ = CkMoveDoIt$
END SUB
FUNCTION LeagMove (PRow AS INTEGER, PColumn AS INTEGER, PieceColor AS INTEGER)
KEY(15) ON
KEY(16) OFF
IF Board(PRow, PColumn) <> 0 THEN
LeagMove = 0
EXIT FUNCTION
END IF
LeagMove = -1
FOR i = 1 TO 9
FlipperL(i) = 0
NEXT i
FlipperL(1) = CheckLeag(PRow, PColumn, PieceColor, -1, -1)
FlipperL(2) = CheckLeag(PRow, PColumn, PieceColor, 0, -1)
FlipperL(3) = CheckLeag(PRow, PColumn, PieceColor, 1, -1)
FlipperL(4) = CheckLeag(PRow, PColumn, PieceColor, -1, 0)
FlipperL(5) = CheckLeag(PRow, PColumn, PieceColor, 0, 0)
FlipperL(6) = CheckLeag(PRow, PColumn, PieceColor, 1, 0)
FlipperL(7) = CheckLeag(PRow, PColumn, PieceColor, -1, 1)
FlipperL(8) = CheckLeag(PRow, PColumn, PieceColor, 0, 1)
FlipperL(9) = CheckLeag(PRow, PColumn, PieceColor, 1, 1)
FOR i = 1 TO 9
IF FlipperL(i) <> 0 THEN EXIT FUNCTION
NEXT i
LeagMove = 0
END FUNCTION
FUNCTION CheckLeag (ORow AS INTEGER, OColumn AS INTEGER, PColor AS INTEGER, RCng AS INTEGER, CCng AS INTEGER)
KEY(15) ON
KEY(16) OFF
CheckLeag = 0
CCure = OColumn + CCng
RCure = ORow + RCng
CurPiece = 1
PiecesSoFar = 0
WHILE RCure > 0 AND RCure < 9 AND CCure > 0 AND CCure < 9 AND CurPiece <> 0
CurPiece = Board(RCure, CCure)
IF CurPiece = PColor THEN
CheckLeag = PiecesSoFar
CurPiece = 0
ELSEIF CurPiece <> 0 THEN
PiecesSoFar = PiecesSoFar + 1
CCure = CCure + CCng
RCure = RCure + RCng
END IF
WEND
END FUNCTION
The temp / 0 is simply to catch the computer at trying to make an illegal move and break the execution. Thanks ahead of time for your help.
EDIT: I made a mistake, the Out of Stack error no longer appers. Also, I updated my program (fixed a few bugs I didn't realize were there, and made it no longer depend on the two header (.bi) files. Here is the updated version: Othello.bas. You no longer need to download the two header files. I also found that the AI isn't as good as I want it to be (it often makes stupid moves). I would welcome any help on the AI also. The logic for the AI is in the sub AIMove.
EDIT 2: The AI no longer tries to make illeagal moves. I updated the code in this post.