liarsdice_cbarcroft 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []