-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoker.rb
238 lines (187 loc) · 5.27 KB
/
poker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# ゲームの本体
DEFAULT_SCREEN_W = 1000
DEFAULT_SCREEN_H = 700
require "mygame/boot"
require "./card_deck.rb"
require "./card_player.rb"
require "./poker_logic.rb"
class Poker
include CardDeck
include CardPlayer
extend PokerLogic
# クラス定数
# 手札の表示位置
PLAYER_X = 250
PLAYER_Y = DEFAULT_SCREEN_H - 100
DEALER_X = 250
DEALER_Y = 100
CARD_MERGIN = 120
SELECTED_CARD_POP = 50
# フォント用
RED = [255, 0, 0]
GREEN = [0, 255, 0]
FONT_SIZE = 20
# メッセージ用
MESSAGE_X = 10
MESSAGE_Y = 400
MATCH_MESSAGE_X = 50
MATCH_MESSAGE_Y = 500
RANK_X = 200
PLAYER_RANK_Y = DEFAULT_SCREEN_H - 220
DEALER_RANK_Y = 200
MESSAGE_MERGIN = 30
def initialize
@deck = CardDeck::Deck.new
@player = CardPlayer::Player.new(PokerLogic::HAND, @deck)
@dealer = CardPlayer::Player.new(PokerLogic::HAND, @deck)
# 山札表示用の中身の無いカード
@back_card = CardDeck::Card.back(DEFAULT_SCREEN_W/2, DEFAULT_SCREEN_H/2)
@win = 0
@lose = 0
@result = "win: #{@win}, lose: #{@lose}"
@match = false
@winner = nil
# 手札の表示位置を設定
hand_rocation(@player.hand, PLAYER_X, PLAYER_Y)
hand_rocation(@dealer.hand, DEALER_X, DEALER_Y)
# ディーラーの手札を裏に
@dealer.turn_cards
set_bg
end
def render
@bg.render
@player.hand.each {|card| card.render}
@dealer.hand.each {|card| card.render}
@back_card.render
display_font(@result, MESSAGE_X, MESSAGE_Y-MESSAGE_MERGIN*3)
if @match
display_rank
display_font("Push Enter for next game", MESSAGE_X, MESSAGE_Y, GREEN)
display_match_message
else
display_font("Click cards you want to discard", MESSAGE_X, MESSAGE_Y, GREEN)
display_font("Push Enter to discard and have a match", MESSAGE_X, MESSAGE_Y+MESSAGE_MERGIN, GREEN)
end
end
private
# 山札と手札をリセット
def reset
@deck.reset
@player.make_hand
@dealer.make_hand
hand_rocation(@player.hand, PLAYER_X, PLAYER_Y)
hand_rocation(@dealer.hand, DEALER_X, DEALER_Y)
@dealer.turn_cards
@match = false
end
# 背景画像をセット
def set_bg
@bg = Image.new("images/bg.png")
@bg.x = 0
@bg.y = 0
end
# 文字の表示の基本設定
def display_font(content, x, y, color=nil, size=FONT_SIZE)
fnt = Font.new(content)
fnt.x = x
fnt.y = y
fnt.ttf_path = "fonts/SourceCodePro-Regular.ttf"
fnt.size = size
fnt.color = color if color
fnt.render
end
# 役の名前を表示
def display_rank
player_rank = Poker.rank_string(@player.hand)
dealer_rank = Poker.rank_string(@dealer.hand)
display_font(player_rank, RANK_X, PLAYER_RANK_Y, RED)
display_font(dealer_rank, RANK_X, DEALER_RANK_Y, RED)
end
# 勝敗の結果を表示
def display_match_message
if @winner == @player
display_font("You win!!", MATCH_MESSAGE_X, MATCH_MESSAGE_Y, [255, 153, 0])
elsif @winner == @dealer
display_font("You lose...", MATCH_MESSAGE_X, MATCH_MESSAGE_Y, [102, 102, 255])
else
display_font("Draw", MATCH_MESSAGE_X, MATCH_MESSAGE_Y, [255, 255, 0])
end
end
# 手札の表示位置の設定
def hand_rocation(hand, start_x, start_y)
hand.each_index do |index|
hand[index].x = index * CARD_MERGIN + start_x
hand[index].y = start_y
end
end
# カードをクリックされた時の処理
def click_event(event)
@player.hand.each do |card|
card.click if card.clicked?(event)
card.y -= SELECTED_CARD_POP if card.clicked and card.y == PLAYER_Y
card.y += SELECTED_CARD_POP unless card.clicked or card.y == PLAYER_Y
end
end
# 手札を交換
def exchange_hand(player = @player)
discard_num = player.hand.map {|card| card.clicked}.count(true)
player.discard
discard_num.times { player.draw }
x = player == @player ? PLAYER_X : DEALER_X
y = player == @player ? PLAYER_Y : DEALER_Y
hand_rocation(player.hand, x, y)
end
# ディーラーの手札交換
def dealer_change
rank = Poker.rank_string(@dealer.hand)
nums = @dealer.hand.map {|card| card.number}
case rank
when "HighCards"
@dealer.hand.each {|card| card.click}
when "OnePair", "TwoPair", "ThreeOfKind"
@dealer.hand.each {|card| card.click if nums.count(card.number) == 1}
end
exchange_hand(@dealer)
@dealer.hand.each {|card| card.turn if card.face == false}
end
# 勝負後の処理
def match
@winner = Poker.match(@player, @dealer)
if @winner == @player
@win += 1
else
@lose += 1
end
@result = "win: #{@win} lose: #{@lose}"
@match = true
end
end
poker = Poker.new
# イベント処理
match_flag = true
# クリックの処理
MyGame.add_event(:mouse_button_down) do |event|
poker.send(:click_event, event)
end
# Enterの挙動
MyGame.add_event(:key_down) do |event|
if event.sym == MyGame::Key::RETURN
# 勝負後
if match_flag
poker.send(:exchange_hand)
poker.send(:dealer_change)
poker.send(:match)
match_flag = false
# 捨てるカードを選ぶとき
else
poker.send(:reset)
match_flag = true
end
end
# ESCで終了
exit(0) if event.sym == MyGame::Key::ESCAPE
end
# メインループ
main_loop do
poker.render
end