tictactoe-randall 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/Board.rb ADDED
@@ -0,0 +1,305 @@
1
+ class Board
2
+
3
+ include GladeGUI
4
+
5
+ def show()
6
+ @path = File.dirname(__FILE__) + "/"
7
+
8
+ load_glade(__FILE__) #loads file, glade/MyClass.glade into @builder
9
+ @image1 = @path + "blank.jpg"
10
+ @image2 = @path + "blank.jpg"
11
+ @image3 = @path + "blank.jpg"
12
+ @image4 = @path + "blank.jpg"
13
+ @image5 = @path + "blank.jpg"
14
+ @image6 = @path + "blank.jpg"
15
+ @image7 = @path + "blank.jpg"
16
+ @image8 = @path + "blank.jpg"
17
+ @image9 = @path + "blank.jpg"
18
+ @label1 = "Welcome to Tic Tac Toe"
19
+ #array to store image names; this will make updating the board easier
20
+ @images = { 'X' => "x.jpg", 'O' => "o.jpg" }
21
+ set_glade_all() #populates glade controls with insance variables (i.e. Myclass.label1)
22
+
23
+ newmatch()
24
+ show_window()
25
+ end
26
+
27
+ #Human opponent
28
+ def radiobutton1__clicked(*argv)
29
+ if @tictactoe.player2.type != 'human'
30
+ if @tictactoe.movenum == 0 or @tictactoe.winner != ''
31
+ @tictactoe.SelectPlayers(2)
32
+
33
+ if @tictactoe.winner != '' then newgame() end
34
+
35
+ #clear all difficulty selectors
36
+ @builder["checkbutton1"].active = false
37
+ @builder["checkbutton2"].active = false
38
+ @builder["checkbutton3"].active = false
39
+
40
+ #update player names and status
41
+ @builder["label4"].text = @tictactoe.player1.name
42
+ @builder["label3"].text = @tictactoe.player2.name
43
+ @builder["label5"].text = 'Now playing human. ' + @tictactoe.PrintInstructions()
44
+
45
+ #clear and update scores
46
+ ResetScore()
47
+ else
48
+ #toggle back
49
+ @builder["radiobutton2"].active = true
50
+ @builder["label5"].text = 'Cannot change opponent during game'
51
+ end
52
+ end
53
+ end
54
+
55
+ #Computer opponent
56
+ def radiobutton2__clicked(*argv)
57
+ if @tictactoe.player2.type != 'computer'
58
+ if @tictactoe.movenum == 0 or @tictactoe.winner != ''
59
+ @tictactoe.SelectPlayers(1)
60
+ if @tictactoe.winner != '' then newgame() end
61
+
62
+ #select easy difficulty by default
63
+ @builder["checkbutton1"].active = true
64
+
65
+ #update player names
66
+ @builder["label4"].text = @tictactoe.player1.name
67
+ @builder["label3"].text = @tictactoe.player2.name
68
+
69
+ #clear and update scores
70
+ ResetScore()
71
+ else
72
+ #toggle back
73
+ @builder["radiobutton1"].active = true
74
+ @builder["label5"].text = 'Cannot change opponent during game'
75
+ end
76
+ end
77
+ end
78
+
79
+ #Easy difficulty
80
+ def checkbutton1__clicked(*argv)
81
+ if @builder["radiobutton2"].active? == false
82
+ #Only allow player to select difficulty if opponent is computer
83
+ @builder["checkbutton1"].active = false
84
+ elsif @builder["checkbutton1"].active? == true and (@tictactoe.movenum == 0 or @tictactoe.winner != '')
85
+ @builder["checkbutton2"].active = false
86
+ @builder["checkbutton3"].active = false
87
+ @tictactoe.SetDifficulty('easy')
88
+ @builder["label5"].text = 'Now playing computer on easy. '+ @tictactoe.PrintInstructions()
89
+ elsif not (@tictactoe.movenum == 0 or @tictactoe.winner != '')
90
+ #toggle back
91
+ @builder["checkbutton1"].active = (@tictactoe.difficulty == 'easy')
92
+ @builder["label5"].text = 'Cannot change difficulty during game'
93
+ end
94
+ end
95
+
96
+ #Normal difficulty
97
+ def checkbutton2__clicked(*argv)
98
+ if @builder["radiobutton2"].active? == false
99
+ #Only allow player to select difficulty if opponent is computer
100
+ @builder["checkbutton2"].active = false
101
+ elsif @builder["checkbutton2"].active? == true and (@tictactoe.movenum == 0 or @tictactoe.winner != '')
102
+ @builder["checkbutton1"].active = false
103
+ @builder["checkbutton3"].active = false
104
+ @tictactoe.SetDifficulty('normal')
105
+ @builder["label5"].text = 'Now playing computer on normal. '+ @tictactoe.PrintInstructions()
106
+ elsif not (@tictactoe.movenum == 0 or @tictactoe.winner != '')
107
+ #toggle back
108
+ @builder["checkbutton2"].active = (@tictactoe.difficulty == 'normal')
109
+ @builder["label5"].text = 'Cannot change difficulty during game'
110
+ end
111
+ end
112
+
113
+ #Hard difficulty
114
+ def checkbutton3__clicked(*argv)
115
+ if @builder["radiobutton2"].active? == false
116
+ #Only allow player to select difficulty if opponent is computer
117
+ @builder["checkbutton3"].active = false
118
+ elsif @builder["checkbutton3"].active? == true and (@tictactoe.movenum == 0 or @tictactoe.winner != '')
119
+ @builder["checkbutton1"].active = false
120
+ @builder["checkbutton2"].active = false
121
+ @tictactoe.SetDifficulty('hard')
122
+ @builder["label5"].text = 'Now playing computer on hard. '+ @tictactoe.PrintInstructions()
123
+ elsif not (@tictactoe.movenum == 0 or @tictactoe.winner != '')
124
+ #toggle back
125
+ @builder["checkbutton3"].active = (@tictactoe.difficulty == 'hard')
126
+ @builder["label5"].text = 'Cannot change difficulty during game'
127
+ end
128
+ end
129
+
130
+ #Menu options
131
+ def imagemenuitem1__activate(*argv)
132
+ #Game -> New
133
+ newgame()
134
+ end
135
+
136
+ def imagemenuitem2__activate(*argv)
137
+ #Game -> Reset score
138
+ ResetScore()
139
+ end
140
+
141
+ def imagemenuitem5__activate(*argv)
142
+ #Game -> Exit
143
+ destroy_window()
144
+ end
145
+
146
+ def imagemenuitem6__activate(*argv)
147
+ #Edit -> Undo
148
+ if @tictactoe.winner == ''
149
+ #Cannot undo winning move
150
+ lastmoveindex = @tictactoe.GetLastMove()
151
+ penultimatemoveindex = @tictactoe.GetPenultimateMove()
152
+ status = @tictactoe.UndoMove()
153
+ @builder["label5"].text = status
154
+ if status == 'Move undone'
155
+ @builder["image" + (lastmoveindex+1).to_s].file = @path + "blank.jpg"
156
+ if @tictactoe.player2.type == 'computer'
157
+ @builder["image" + (penultimatemoveindex+1).to_s].file = @path + "blank.jpg"
158
+ end
159
+ end
160
+ else
161
+ @builder["label5"].text = 'Cannot undo winning move'
162
+ end
163
+ end
164
+
165
+ def imagemenuitem10__activate(*argv)
166
+ #Help -> About
167
+ modal_win = ModalWindow.new
168
+ modal_win.show(self)
169
+ end
170
+
171
+ #Move buttons 1 - 9
172
+ def button1__clicked(*argv)
173
+ if makemove(1) and @tictactoe.player2.type == 'computer' then
174
+ computermove()
175
+ end
176
+ end
177
+
178
+ def button2__clicked(*argv)
179
+ if makemove(2) and @tictactoe.player2.type == 'computer' then
180
+ computermove()
181
+ end
182
+ end
183
+
184
+ def button3__clicked(*argv)
185
+ if makemove(3) and @tictactoe.player2.type == 'computer' then
186
+ computermove()
187
+ end
188
+ end
189
+
190
+ def button4__clicked(*argv)
191
+ if makemove(4) and @tictactoe.player2.type == 'computer' then
192
+ computermove()
193
+ end
194
+ end
195
+
196
+ def button5__clicked(*argv)
197
+ if makemove(5) and @tictactoe.player2.type == 'computer' then
198
+ computermove()
199
+ end
200
+ end
201
+
202
+ def button6__clicked(*argv)
203
+ if makemove(6) and @tictactoe.player2.type == 'computer' then
204
+ computermove()
205
+ end
206
+ end
207
+
208
+ def button7__clicked(*argv)
209
+ if makemove(7) and @tictactoe.player2.type == 'computer' then
210
+ computermove()
211
+ end
212
+ end
213
+
214
+ def button8__clicked(*argv)
215
+ if makemove(8) and @tictactoe.player2.type == 'computer' then
216
+ computermove()
217
+ end
218
+ end
219
+
220
+ def button9__clicked(*argv)
221
+ if makemove(9) and @tictactoe.player2.type == 'computer' then
222
+ computermove()
223
+ end
224
+ end
225
+
226
+
227
+ private
228
+
229
+ def newmatch()
230
+ @tictactoe = TicTacToe.new()
231
+ @tictactoe.SelectPlayers(2)
232
+ @builder["label4"].text = @tictactoe.player1.name
233
+ @builder["label8"].text = @tictactoe.player1.score.to_s
234
+
235
+ @builder["label3"].text = @tictactoe.player2.name
236
+ @builder["label7"].text = @tictactoe.player2.score.to_s
237
+
238
+ @builder["label2"].text = @tictactoe.cat.name
239
+ @builder["label6"].text = @tictactoe.cat.score.to_s
240
+
241
+ @builder["label5"].text = 'New game - ' + @tictactoe.PrintInstructions()
242
+ end
243
+
244
+ def newgame()
245
+ @tictactoe.Reset()
246
+ @builder["label5"].text = 'New game - ' + @tictactoe.PrintInstructions()
247
+ @builder["image1"].file = @path + "blank.jpg"
248
+ @builder["image2"].file = @path + "blank.jpg"
249
+ @builder["image3"].file = @path + "blank.jpg"
250
+ @builder["image4"].file = @path + "blank.jpg"
251
+ @builder["image5"].file = @path + "blank.jpg"
252
+ @builder["image6"].file = @path + "blank.jpg"
253
+ @builder["image7"].file = @path + "blank.jpg"
254
+ @builder["image8"].file = @path + "blank.jpg"
255
+ @builder["image9"].file = @path + "blank.jpg"
256
+ if @tictactoe.player2.type == 'computer' and @tictactoe.player2.mark == 'X' then computermove() end
257
+ end
258
+
259
+ def ResetScore()
260
+ @tictactoe.ClearScore()
261
+ @builder["label8"].text = @tictactoe.player1.score.to_s
262
+ @builder["label7"].text = @tictactoe.player2.score.to_s
263
+ @builder["label6"].text = @tictactoe.cat.score.to_s
264
+ end
265
+
266
+ def makemove(space)
267
+ if @tictactoe.SpaceAvailable(space)
268
+ @builder["image"+space.to_s].file = @path + @images[@tictactoe.currentturn]
269
+ @tictactoe.MakeMove(space)
270
+ winner = @tictactoe.CheckWinner(space)
271
+ if winner == ''
272
+ @tictactoe.SwapTurn()
273
+ else
274
+ gameover(winner)
275
+ end
276
+ return true
277
+ else
278
+ return false
279
+ end
280
+ end
281
+
282
+ def computermove()
283
+ if @tictactoe.winner == ''
284
+ space = @tictactoe.ComputerMove()
285
+ @builder["label5"].text = 'Computer chooses ' + space.to_s
286
+ makemove(space)
287
+ end
288
+ end
289
+
290
+ def gameover(winner)
291
+ @tictactoe.UpdateScore(winner)
292
+
293
+ @builder["label5"].text = @tictactoe.PrintWinner()
294
+ @builder["label8"].text = @tictactoe.player1.score.to_s
295
+ @builder["label7"].text = @tictactoe.player2.score.to_s
296
+ @builder["label6"].text = @tictactoe.cat.score.to_s
297
+
298
+ #After each game, alternate who goes first
299
+ @tictactoe.SwapPlayers()
300
+
301
+ end
302
+
303
+
304
+ end
305
+
@@ -0,0 +1,25 @@
1
+
2
+ ##
3
+ # This is a modal window. In glade, you'll see that the "Modal"
4
+ # setting is true (default in VR). This means that everything
5
+ # will halt until it finishes.
6
+ #
7
+ # Notice that this window doesn't need to set a parent window
8
+ # because having it close with its parent isn't an issue--the user is
9
+ # forced to terminate this window first.
10
+ #
11
+ # Note: The "Cancel" button on this window is directly linked to the
12
+ # destroy_window method (in GladeGUI), so you don't need to write your own method to
13
+ # handle when the Cancel button is clicked.
14
+ #
15
+
16
+ class ModalWindow #(change name)
17
+
18
+ include GladeGUI
19
+
20
+ def show(parent)
21
+ load_glade(__FILE__, parent)
22
+ show_window()
23
+ end
24
+
25
+ end
data/bin/blank.jpg ADDED
Binary file