September 23, 2019, 03:11:50 PM

### Author Topic: Four in a row  (Read 142 times)

• Sr. Member
• Posts: 429
##### Four in a row
« on: August 24, 2019, 09:22:01 PM »
Was digging through some old programs of mine and found this one.  It is a port from "More Basic Computer Games" converted to BlitzMax.  Game is similar to Connect 4.  Complete with computer AI.
Code: BlitzMax
1. '**********************************************************
2. '*
3. '*    Four in a Row
5. '*    Adapted from code by James L Murphy which appears in
6. '*       More Basic Computer Games
7. '*   https://www.atariarchives.org/morebasicgames/showpage.php?page=63
8. '*
9. '**********************************************************
10. SuperStrict
11.
12. Graphics 800,600
13. While Not MouseHit(1)
14.         If KeyHit(KEY_ESCAPE) Or AppTerminate() Then End
15.         Cls
16.         SetScale 3,3
17.         DrawText "Four in a Row",10,10
18.         SetScale 2,2
19.         DrawText "Click mouse button to continue",10,100
20.         Flip
21. Wend
22.
23. SetScale 1,1
24. Local BoardImage:TImage = CreateImage(512,512)
25. Cls
26. SetColor 255,255,0
27. DrawRect 0,0,512,512
28. SetColor 0,0,0
29. For Local x:Int = 0 To 7
30.         For Local y:Int = 0 To 7
31.                 DrawOval x*64+8,y*64+8,48,48
32.         Next
33. Next
34. SetColor 255,255,255
35. GrabImage BoardImage,0,0
36.
37. Global Board:Int[8,8], l:Int[8], s:Int[4], f:Int[4], v:Int[16], n:Int[4]
38. DefData 1,100,500,2^20,1,800,4000,2^20
39. DefData 1,75,900,2^18,1,450,3000,2^18
40.
41. For Local i:Int = 0 To 15
43. Next
44.
45. For Local i:Int = 0 To 7
46.         For Local j:Int = 0 To 7
47.                 board[i,j] = 0
48.         Next
49.         l[i] = 0
50. Next
51.
52. Local State:Int, MX:Int, MY:Int
53. Const STATE_PICKTURN:Int = 0
54. Const STATE_PLAYERTURN:Int = 1
55. Const STATE_COMPTURN:Int = 2
56. Const STATE_PLAYERANIM:Int = 3
57. Const STATE_CHECKPLAYER:Int = 4
58. Const STATE_COMPANIM:Int = 5
59. Const STATE_CHECKCOMP:Int = 6
60. Const STATE_PLAYERWINS:Int = 7
61. Const STATE_COMPWINS:Int = 8
62. Const STATE_TIE:Int = 9
63.
64. While State = STATE_PICKTURN
65.         If KeyHit(KEY_ESCAPE) Or AppTerminate() Then End
66.         Cls
67.         SetScale 4,4
68.         DrawText "Who goes first?",10,10
69.         SetScale 1,1
70.         DrawRect 10,100,400,60
71.         DrawRect 10,170,400,60
72.         SetColor 0,0,0
73.         SetScale 3,3
74.         DrawText "Me!!!!",15,105
75.         DrawText "Computer",15,175
76.         Flip
77.         SetColor 255,255,255
78.         If MouseHit(1)
79.                 MX:Int = MouseX()
80.                 MY:Int = MouseY()
81.
82.                 If MX > 10 And MX < 410 And MY > 100 And MY < 160 Then State = STATE_PLAYERTURN
83.                 If MX > 10 And MX < 410 And MY > 170 And MY < 230 Then State = STATE_COMPTURN
84.         End If
85. Wend
86.
87. SetScale 1,1
88.
89. Local Animate:Int = False, Column:Int, Drop:Int, Result:Int[]
90. Local AnimX:Float, AnimY:Float, AnimStartTime:Int, AnimTime:Int,dy:Float,Delta:Float
91. While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
92.         MX = MouseX()
93.         MY = MouseY()
94.         Cls
95.         If state = STATE_PLAYERANIM Or State = STATE_COMPANIM
96.                 AnimTime = MilliSecs() - AnimStartTime
97.                 If STate = STATE_PLAYERANIM
98.                         SetColor 192,192,192
99.                 Else
100.                         SetColor 192,0,0
101.                 End If
102.                 delta = Float(AnimTime)/500
103.                 dy:Float = delta*512.0
104.                 DrawOval Animx,dy,60,60
105.                 If State = STATE_PLAYERANIM
106.                         SetColor 255,255,255
107.                 Else
108.                         SetColor 255,0,0
109.                 End If
110.                 DrawOval Animx+2,dy+2,56,56
111.                 If dy >= AnimY
112.                         If State = STATE_PLAYERANIM
113.                                 State = STATE_CHECKPLAYER
114.                         Else
115.                                 State = STATE_CHECKCOMP
116.                         End If
117.                 End If
118.         End If
119.         SetColor 255,255,255
120.         DrawImage BoardImage,144,64
121.         For Local x:Int = 0 To 7
122.                 For Local y:Int = 0 To 7
123.                         Select Board[x,y]
124.                                 Case 0
125.                                         SetColor 0,0,0
126.                                 Case 1
127.                                         SetColor 255,255,255
128.                                 Case 2
129.                                         SetColor 255,0,0
130.                         End Select
131.                         If Board[x,y] > 0 Then DrawOval x*64+152,y*64+72,48,48
132.                 Next
133.         Next
134.         SetColor 0,0,255
135.         DrawRect 124,576,552,24
136.         If State = STATE_PLAYERTURN
137.                 SetColor 192,192,192
138.                 DrawOval MX-30,MY-30,60,60
139.                 SetColor 255,255,255
140.                 DrawOval MX-28,MY-28,56,56
141.         End If
142.         If State = STATE_PLAYERWINS
143.                 SetColor 255,255,255
144.                 SetScale 2,2
145.                 DrawText "Player Wins!!!!",10,10
146.                 SetScale 1,1
147.         End If
148.         If State = STATE_COMPWINS
149.                 SetColor 255,0,0
150.                 SetScale 2,2
151.                 DrawText "Computer Wins!!!!",10,10
152.                 SetScale 1,1
153.         End If
154.         If State = STATE_TIE
155.                 SetColor 0,255,0
156.                 SetScale 2,2
157.                 DrawText "Tie Game!!!!!!",10,10
158.                 SetScale 1,1
159.         End If
160.         Flip
161.
162.         Select State
163.                 Case STATE_PLAYERTURN
164.                         State = STATE_TIE
165.                         For Local i:Int = 0 To 7
166.                                 If l[i] < 7
167.                                         State = STATE_PLAYERTURN
168.                                         Exit
169.                                 End If
170.                         Next
171.                         If State = STATE_TIE Then Continue
172.                         If MouseHit(1)
173.                                 Column = (MX - 144)/64
174.                                 If Column < 0 Or Column > 7 Or MY > 64 Or Board[Column,0] <> 0 Then Continue
175.                                 State = STATE_PLAYERANIM
176.                                 AnimX = Column * 64 + 144
177.                                 AnimY = (8-l[Column])*64
178.                                 AnimStartTime = MilliSecs()
179.                         End If
180.                 Case STATE_CHECKPLAYER
181.                         Drop:Int = 7 -l[Column]
182.                         Board[Column,Drop] = 1
183.                         l[Column] :+ 1
184.                         'Check for four in a row
185.                         Local Result:Int[] = CheckConnect(Column,Drop,State)
186.                         State = STATE_COMPTURN
187.                         For Local i:Int = 0 To 3
188.                                 If Result[i] >= 4
189.                                         State = STATE_PLAYERWINS
190.                                         Exit
191.                                 End If
192.                         Next
193.                 Case STATE_COMPTURN
194.                         State = STATE_TIE
195.                         For Local i:Int = 0 To 7
196.                                 If l[i] < 7 Then State = STATE_COMPTURN
197.                                 Exit
198.                         Next
199.                         If State = STATE_TIE Then Continue
200.                         Local MaxValue:Int = 0, Move:Int = -1
201.                         For Column = 0 To 7
202.                                 Local CheckValue:Int = 0
203.                                 Drop = 7 - l[Column]
204.                                 If Drop > 7 Then Continue
205.                                 Result = CheckConnect(Column,Drop,State)
206.                                 Local Bonus:Int = 0
207.                                 For Local Count:Int = 1 To 4
208.                                         For Local i:Int = 0 To 3
209.                                                 If Result[i] = Count
210.                                                         CheckValue :+ V[(Count-1)+4*Bonus]
211.                                                         Bonus = 1
212.                                                 End If
213.                                         Next
214.                                 Next
215.                                 Result = CheckConnect(Column,Drop,STATE_CHECKPLAYER)
216.                                 Bonus:Int = 0
217.                                 For Local Count:Int = 1 To 4
218.                                         For Local i:Int = 0 To 3
219.                                                 If Result[i] = Count
220.                                                         CheckValue :+ V[(Count-1)+4*Bonus+8]
221.                                                         Bonus = 1
222.                                                 End If
223.                                         Next
224.                                 Next
225.                                 If CheckValue > MaxValue
226.                                         MaxValue = CheckValue
227.                                         Move = Column
228.                                 Else If CheckValue = MaxValue
229.                                         If Rand(0,1) Then Move = Column
230.                                 End If
231.                         Next
232.                         Column = Move
233.                         State = STATE_COMPANIM
234.                         AnimX = Move * 64 + 144
235.                         AnimY = (8-l[Move])*64
236.                         AnimStartTime = MilliSecs()
237.                 Case STATE_CHECKCOMP
238.                         Drop = 7 - l[Column]
239.                         Board[Column,Drop] = 2
240.                         l[Column] :+ 1
241.                         Result = CheckConnect(Column,Drop,State)
242.                         State = STATE_PLAYERTURN
243.                         For Local i:Int = 0 To 3
244.                                 If Result[i] >= 4 Then State = STATE_COMPWINS
245.                         Next
246.
247.         End Select
248. Wend
249.
250. Function CheckConnect:Int[](Column:Int, Drop:Int, State:Int)
251.         Local Result:Int[4]
252.         Local Check:Int
253.
254.         If State = STATE_CHECKPLAYER
255.                 Check = 1
256.         Else
257.                 Check = 2
258.         End If
259.
260.         Result[0] = CheckDirection(Column,Drop,1,0,Check)
261.         Result[1] = CheckDirection(Column,Drop,1,1,Check)
262.         Result[2] = CheckDirection(Column,Drop,0,1,Check)
263.         Result[3] = CheckDirection(Column,Drop,-1,1,Check)
264.         Return Result
265. End Function
266.
267. Function CheckDirection:Int(Column:Int, Drop:Int, DirX:Int, DirY:Int, Check:Int)
268.         Local Total:Int = 1
269.         For Local d:Int = 0 To 1
270.                 For Local i:Int = 1 To 3
271.                 If Total = 4 Then Exit
272.                         Local x:Int = Column+DirX*i, y:Int = Drop+DirY*i
273.                         If x < 0 Or x > 7 Or y < 0 Or y > 7 Then Exit
274.                         If Board[x,y] = Check
275.                                 Total :+ 1
276.                         Else
277.                                 Exit
278.                         End If
279.                 Next
280.                 DirX = -DirX
281.                 DirY = -DirY
282.         Next
284. End Function
285.
286.
Original Basic code: https://www.atariarchives.org/morebasicgames/showpage.php?page=63
------------------------------------------------
8 rabbits equals 1 rabbyte.

#### Steve Elliott

• Hero Member
• Posts: 2000
##### Re: Four in a row
« Reply #1 on: August 25, 2019, 08:29:53 AM »
Very nice, and from the few goes I've just had quite challenging too.

You did well to convert it to BM because the original BASIC version was awful!  No indentation and frequent use of the goto command!
Windows 10, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
MacOS Mojave, 64-bit, 8Gb RAM, CPU Intel i5, 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB.
Linux Mint 19.1, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
Raspbian Buster, pi4 4Gb RAM,1.5Ghz

• Sr. Member
• Posts: 429
##### Re: Four in a row
« Reply #2 on: August 25, 2019, 12:43:50 PM »
Quote
the original BASIC version was awful!  No indentation and frequent use of the goto command!
That was pretty much necessary with BASIC back in the early 80's and earlier.  No way to indent, which would only result in slower code anyway as the interpreter would have to spend time skipping the spaces.  Also, early BASIC was not structured, so you would require goto for IF/THEN/ELSE structures and WHILE/DO/REPEAT type structures. Another problem with most implementation of BASIC is variable names.  Usually, only the first 2 characters are significant, so VEC1, VEC2, and VEC3 would all refer to the same variable, you had to use V1, V2, and V3 instead.  Also, variables couldn't contain keywords within them, so TOP couldn't be a variable as it contained the keyword TO.

I wrote many programs on my C64 this way.  Had both the books, "BASIC Computer Games" and "More BASIC Computer Games," and had typed many of the programs into my C64.
------------------------------------------------
8 rabbits equals 1 rabbyte.

#### Steve Elliott

• Hero Member
• Posts: 2000
##### Re: Four in a row
« Reply #3 on: August 25, 2019, 01:06:54 PM »
Quote
That was pretty much necessary with BASIC back in the early 80's and earlier.

Yes I know, I used those types of BASIC back then too.  It's just a shock seeing how atrocious that mass of characters looks these days.
Windows 10, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
MacOS Mojave, 64-bit, 8Gb RAM, CPU Intel i5, 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB.
Linux Mint 19.1, 64-bit, 16Gb RAM, CPU Intel i5, 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb).
Raspbian Buster, pi4 4Gb RAM,1.5Ghz