liarsdice_cbarcroft 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/liarsdice ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ require 'liars_dice.rb'
3
+
4
+ @game = LiarsDice.new
5
+ puts @game.welcome_player
6
+
7
+ until @game.over?
8
+ case @game.current_player
9
+ when "Computer"
10
+ @game.computer_move
11
+ when @game.player
12
+ @game.indicate_player_turn
13
+ @game.player_move
14
+ end
15
+ @game.current_state
16
+ @game.determine_winner
17
+ end
18
+
19
+ puts "You win!" if @game.player_won?
20
+ puts "Computer wins!" if @game.computer_won?
@@ -0,0 +1,65 @@
1
+ Feature: Liar's Dice Game
2
+ As a Ruby student I need a final project
3
+ In order to pass the class
4
+ I would like to play the computer at Liars Dice
5
+
6
+ Scenario: Start Game
7
+ Given I start a new game
8
+ When I enter my name as Chris
9
+ Then the computer welcomes me to the game with "Welcome, Chris!"
10
+ And randomly chooses who goes first
11
+ And rolls five random dice for each player
12
+
13
+ Scenario: My Turn
14
+ Given I have a started a game
15
+ And it is my turn
16
+ And the computer knows my name is Chris
17
+ Then the computer prints "Chris's turn:"
18
+ And waits for my input of "FACE 2"
19
+
20
+ Scenario: Computer's Turn
21
+ Given I have a started a game
22
+ And it is the computer's turn
23
+ Then the computer randomly chooses an open position for its move
24
+ And the board should have an X on it
25
+
26
+ Scenario: Making Moves
27
+ Given I have a started a game
28
+ And it is my turn
29
+ When I enter a bet of "FACE 2"
30
+ And "FACE 2" is a legal bet
31
+ Then the face bet should now be 2
32
+ And it is now the computer's turn
33
+
34
+ Scenario: Making Bad Moves
35
+ Given I have a started Tic-Tac-Toe game
36
+ And it is my turn
37
+ And I am playing X
38
+ When I enter a position "A1" on the board
39
+ And "A1" is taken
40
+ Then computer should ask me for another position "B2"
41
+ And it is now the computer's turn
42
+
43
+ Scenario: Calling a bet successfully
44
+ Given I have a started a game
45
+ And it is my turn
46
+ And the current bet is face 2, count 4
47
+ And there are three twos
48
+ When I enter a bet of "OVER"
49
+ And "OVER" is a legal bet
50
+ Then the over bet is successful
51
+ And it is now the computer's turn
52
+
53
+ Scenario: Winning the Game
54
+ Given I have a started Tic-Tac-Toe game
55
+ And I am playing X
56
+ When there are three X's in a row
57
+ Then I am declared the winner
58
+ And the game ends
59
+
60
+ Scenario: Game is a draw
61
+ Given I have a started Tic-Tac-Toe game
62
+ And there are not three symbols in a row
63
+ When there are no open spaces left on the board
64
+ Then the game is declared a draw
65
+ And the game ends
@@ -0,0 +1,131 @@
1
+ require 'rspec/mocks/standalone'
2
+ require '../../liars_dice.rb'
3
+
4
+ Given /^I start a new game$/ do
5
+ @game = LiarsDice.new
6
+ end
7
+
8
+ When /^I enter my name as (\w+)$/ do |name|
9
+ @game.player = name
10
+ end
11
+
12
+ Then /^the computer welcomes me to the game with "(.*?)"$/ do |arg1|
13
+ @game.welcome_player.should eq arg1
14
+ end
15
+
16
+ Then /^randomly chooses who goes first$/ do
17
+ [@game.player, "Computer"].should include @game.current_player
18
+ end
19
+
20
+ Then /^rolls five random dice for each player$/ do
21
+ (@game.dice[:player] + @game.dice[:computer]).length.should eq 10
22
+ end
23
+
24
+ Given /^I have a started a game$/ do
25
+ @game = LiarsDice.new(:player)
26
+ @game.player = "Chris"
27
+ end
28
+
29
+ Given /^it is my turn$/ do
30
+ @game.current_player.should eq "Chris"
31
+ end
32
+
33
+ Given /^the computer knows my name is Chris/ do
34
+ @game.player.should eq "Chris"
35
+ end
36
+
37
+ Then /^the computer prints "(.*?)"$/ do |arg1|
38
+ @game.should_receive(:puts).with(arg1)
39
+ @game.indicate_player_turn
40
+ end
41
+
42
+ Then /^waits for my input of "(.*?)"$/ do |arg1|
43
+ @game.should_receive(:gets).and_return(arg1)
44
+ @game.get_player_move
45
+ end
46
+
47
+ Given /^it is the computer's turn$/ do
48
+ @game = LiarsDice.new(:computer)
49
+ @game.current_player.should eq "Computer"
50
+ end
51
+
52
+ Then /^the computer randomly chooses an open position for its move$/ do
53
+ open_spots = @game.open_spots
54
+ @com_move = @game.computer_move
55
+ open_spots.should include(@com_move)
56
+ end
57
+
58
+ Given /^the computer is playing X$/ do
59
+ @game.computer_symbol.should eq :X
60
+ end
61
+
62
+ Then /^the board should have an X on it$/ do
63
+ @game.current_state.should include 'X'
64
+ end
65
+
66
+ Then /^the (.*?) bet should now be (.*?)$/ do |arg1, arg2|
67
+ @game.current_bet[arg1.to_sym].should eq arg2
68
+ end
69
+
70
+ When /^I enter a bet of "(.*?)"/ do |arg1|
71
+ @game.should_receive(:get_player_move).and_return(arg1)
72
+ end
73
+
74
+ When /^"(.*?)" is a legal bet/ do |arg1|
75
+ @game.validate_player_move(arg1.split(" ")).should eq true
76
+ end
77
+
78
+ When /^the current bet is face (.*?), count (.*?)/ do |arg1, arg2|
79
+ @game.current_bet[:face] = arg1
80
+ @game.current_bet[:count] = arg2
81
+ end
82
+
83
+ When /^there are three twos/ do
84
+ @game.dice[:player] = [1,2,3,4,5]
85
+ @game.dice[:computer] = [1,2,2,3,4]
86
+ end
87
+
88
+ Then /^it is now the computer's turn$/ do
89
+ @game.current_player.should eq "Computer"
90
+ end
91
+
92
+ When /^the over bet is successful$/ do
93
+ @game.dice_remaining[:computer].should eq 4
94
+ end
95
+
96
+ Then /^I am declared the winner$/ do
97
+ @game.determine_winner
98
+ @game.player_won?.should be_true
99
+ end
100
+
101
+ Then /^the game ends$/ do
102
+ @game.over?.should be_true
103
+ end
104
+
105
+ Given /^there are not three symbols in a row$/ do
106
+ @game.board = {
107
+ :A1 => :X, :A2 => :O, :A3 => :X,
108
+ :B1 => :X, :B2 => :O, :B3 => :X,
109
+ :C1 => :O, :C2 => :X, :C3 => :O
110
+ }
111
+ @game.determine_winner
112
+ end
113
+
114
+ When /^there are no open spaces left on the board$/ do
115
+ @game.spots_open?.should be_false
116
+ end
117
+
118
+ Then /^the game is declared a draw$/ do
119
+ @game.draw?.should be_true
120
+ end
121
+
122
+ When /^"(.*?)" is taken$/ do |arg1|
123
+ @game.board[arg1.to_sym] = :O
124
+ @taken_spot = arg1.to_sym
125
+ end
126
+
127
+ Then /^computer should ask me for another position "(.*?)"$/ do |arg1|
128
+ @game.board[arg1.to_sym] = ' '
129
+ @game.should_receive(:get_player_move).twice.and_return(@taken_spot, arg1)
130
+ @game.player_move.should eq arg1.to_sym
131
+ end
data/lib/liars_dice.rb ADDED
@@ -0,0 +1,254 @@
1
+ class LiarsDice
2
+ attr_reader :player_move, :computer_won, :player_won, :over, :current_bet, :waiting_player
3
+ attr_accessor :current_state, :dice, :dice_remaining
4
+
5
+ COMMANDS = ["FACE", "COUNT", "OVER", "SPOTON"]
6
+
7
+ def initialize( first_turn = false)
8
+ system("clear")
9
+ @players = {:player => "Player", :computer => "Computer"}
10
+ @current_player = first_turn
11
+ if first_turn == false
12
+ @current_player = [:computer, :player].sample
13
+ end
14
+ @waiting_player = [:computer, :player].select{|player| player != @current_player}[0]
15
+ @current_bet = {:face => 1, :count => 1}
16
+ @dice = {:player => [], :computer => []}
17
+ @dice_remaining = {:player => 5, :computer => 5}
18
+ @computer_won = false
19
+ @player_won = false
20
+ @over = false
21
+ self.roll_dice
22
+ self.current_state
23
+ end
24
+
25
+ def current_player
26
+ @players[@current_player]
27
+ end
28
+
29
+ def player=(str)
30
+ @players[:player] = str
31
+ end
32
+
33
+ def player
34
+ @players[:player]
35
+ end
36
+
37
+ def welcome_player
38
+ "Welcome, #{@players[:player]}!"
39
+ end
40
+
41
+ def indicate_player_turn
42
+ puts "#{@players[@current_player]}'s turn:"
43
+ end
44
+
45
+ def switch_turns
46
+ temp = @current_player
47
+ @current_player = @waiting_player
48
+ @waiting_player = temp
49
+ end
50
+
51
+ def get_player_move
52
+ gets.chomp
53
+ end
54
+
55
+ def player_move
56
+ move = self.get_player_move.split(" ")
57
+ until (self.validate_player_move(move))
58
+ move = self.get_player_move.split(" ")
59
+ end
60
+
61
+ case move[0].upcase
62
+ when "FACE"
63
+ puts "You have raised the face value to #{move[1]}"
64
+ @current_bet[:face] = move[1]
65
+ when "COUNT"
66
+ puts "You have raised the count to #{move[1]}"
67
+ @current_bet[:count] = move[1]
68
+ when "SPOTON"
69
+ puts "You think the bet is spot on."
70
+ self.check_spoton
71
+ when "OVER"
72
+ puts "You think the computer's bet is too high."
73
+ self.check_over
74
+ end
75
+ self.switch_turns
76
+ end
77
+
78
+ def computer_move
79
+ puts "Computer's Turn:"
80
+ sleep(1)
81
+ move = self.smart_select.split(" ")
82
+
83
+ case move[0]
84
+ when "FACE"
85
+ puts "Computer has raised the face value to #{move[1]}"
86
+ @current_bet[:face] = move[1]
87
+ when "COUNT"
88
+ puts "Computer has raised the count to #{move[1]}"
89
+ @current_bet[:count] = move[1]
90
+ when "SPOTON"
91
+ puts "Computer thinks the bet is spot on."
92
+ self.check_spoton
93
+ when "OVER"
94
+ puts "Computer challenges your bet."
95
+ self.check_over
96
+ end
97
+ self.switch_turns
98
+ end
99
+
100
+ def smart_select
101
+ comp_dice = self.get_dice_total
102
+ if comp_dice[@current_bet[:face].to_i] == @current_bet[:count] then #if computer has the current bet showing in its own dice
103
+ if @dice_remaining[:player] <= 2 then #and the player has two or less dice of their own
104
+ return "SPOTON"
105
+ else
106
+ return "COUNT #{@current_bet[:count].to_i + 1}" #increment count by one
107
+ end
108
+ elsif (comp_dice[@current_bet[:face].to_i]).to_i < @current_bet[:count].to_i then #if computer has less dice of the current face than the bet
109
+ if (@current_bet[:count].to_i - comp_dice[@current_bet[:face].to_i].to_i) >= 2 then
110
+ return "OVER"
111
+ else
112
+ return "COUNT #{@current_bet[:count].to_i + 1}"
113
+ end
114
+ elsif comp_dice[@current_bet[:face].to_i].to_i > @current_bet[:count].to_i then #if computer has more dice of the current face than the bet
115
+ if (comp_dice[@current_bet[:face].to_i].to_i - @current_bet[:count].to_i) >= 2 then
116
+ return "COUNT #{@current_bet[:count].to_i + 2}"
117
+ else
118
+ return "COUNT #{@current_bet[:count].to_i + 1}"
119
+ end
120
+ else
121
+ return "OVER" #default bet, but this should never happen
122
+ end
123
+ end
124
+
125
+ def validate_player_move(move)
126
+ valid = true
127
+ if !COMMANDS.include? move[0].upcase
128
+ puts "Unrecognized command #{move[0].upcase}"
129
+ valid = false
130
+ end
131
+ if move[0].upcase == "FACE" then
132
+ if move[1] == nil || move[1].to_i < 1 || move[1].to_i > 6 then
133
+ puts "Invalid value(#{move[1]}) for FACE"
134
+ valid = false
135
+ elsif !(move[1].to_i > @current_bet[:face].to_i)
136
+ puts "Face bet must be higher than the current bet: #{@current_bet[:face]}"
137
+ valid = false
138
+ end
139
+ end
140
+ if move[0].upcase == "COUNT" then
141
+ if move[1].to_i == nil || move[1].to_i < 1 || move[1].to_i > 10 then
142
+ puts "Invalid value(#{move[1]}) for FACE"
143
+ valid = false
144
+ elsif !(move[1].to_i > @current_bet[:count].to_i)
145
+ puts "Count bet must be higher than the current bet: #{@current_bet[:count]}"
146
+ valid = false
147
+ end
148
+ end
149
+ valid
150
+ end
151
+
152
+ def roll_dice
153
+ @players.each do |player, name|
154
+ @dice[player] = []
155
+ @dice[player] = @dice_remaining[player].times.map{ rand(1..6) }
156
+ end
157
+ end
158
+
159
+ def check_spoton
160
+ puts self.print_dice(true)
161
+ totals = get_dice_totals
162
+ if totals[@current_bet[:face].to_i] == @current_bet[:count]
163
+ puts "#{@players[@current_player]} is correct! #{@players[@waiting_player]} loses one die!"
164
+ @dice_remaining[@waiting_player] -= 1
165
+ else
166
+ puts "#{@players[@current_player]} is wrong, and loses one die! "
167
+ @dice_remaining[@current_player] -= 1
168
+ end
169
+
170
+ self.reset
171
+ end
172
+
173
+ def check_over
174
+ puts self.print_dice(true)
175
+ totals = get_dice_totals
176
+ if totals[@current_bet[:face].to_i].to_i < @current_bet[:count].to_i
177
+ puts "#{@players[@current_player]} is correct! #{@players[@waiting_player]} loses one die!"
178
+ @dice_remaining[@waiting_player] -= 1
179
+ else
180
+ puts "#{@players[@current_player]} is wrong, and loses one die! "
181
+ @dice_remaining[@current_player] -= 1
182
+ end
183
+
184
+ self.reset
185
+ end
186
+
187
+ def reset
188
+ self.roll_dice
189
+ @current_bet[:face] = 1
190
+ @current_bet[:count] = 1
191
+ end
192
+
193
+ def get_dice_totals
194
+ totals = {1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0}
195
+ (@dice[:player] + @dice[:computer]).flatten.each do |die|
196
+ totals[die] += 1
197
+ end
198
+ totals
199
+ end
200
+
201
+ def get_dice_total
202
+ totals = {1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0}
203
+ @dice[:computer].each do |die|
204
+ totals[die] += 1
205
+ end
206
+ totals
207
+ end
208
+
209
+ def current_state
210
+ puts "Current Bet: Face => #{@current_bet[:face]} Count => #{@current_bet[:count]}"
211
+ puts self.print_dice
212
+ end
213
+
214
+ def print_dice(show_computer = false)
215
+ @dice[:player].each do |die|
216
+ print "|#{die}| "
217
+ end
218
+ print " ************ "
219
+ if show_computer then
220
+ @dice[:computer].each do |die|
221
+ print "|#{die}| "
222
+ end
223
+ else
224
+ @dice[:computer].each do |die|
225
+ print "|X| "
226
+ end
227
+ end
228
+ print "\n"
229
+ end
230
+
231
+ def dice_remaining?
232
+ @dice_remaining[:player].to_i > 0 ? true : false
233
+ end
234
+
235
+ def computer_dice_remaining?
236
+ @dice_remaining[:computer].to_i > 0 ? true : false
237
+ end
238
+
239
+ def over?
240
+ (self.player_won? || self.computer_won?)? true : false
241
+ end
242
+
243
+ def player_won?
244
+ self.computer_dice_remaining? ? false : true
245
+ end
246
+
247
+ def computer_won?
248
+ self.dice_remaining? ? false : true
249
+ end
250
+
251
+ def determine_winner
252
+ @over = self.over?
253
+ end
254
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: liarsdice_cbarcroft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Barcroft
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-11 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Test your wits against a ... challenged computer
15
+ email: ChrisABarcroft@gmail.com
16
+ executables:
17
+ - liarsdice
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/features/liars_dice.feature
22
+ - lib/liars_dice.rb
23
+ - lib/features/step_definitions/liars_dice-steps.rb
24
+ - bin/liarsdice
25
+ homepage: http://www.google.com
26
+ licenses: []
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 1.8.24
46
+ signing_key:
47
+ specification_version: 3
48
+ summary: Liar's dice game against an amazing computer opponent
49
+ test_files: []