-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfloodit.rb
190 lines (178 loc) · 4.72 KB
/
floodit.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
require 'console_splash'
require 'colorize'
require 'catpix'
# Creates a new 2d array of width 'width' and height 'height' filled with
# random colour symbols
def get_board(width, height)
colours = [:red, :blue, :green, :yellow, :cyan, :magenta]
board = Array.new(height){Array.new(width, :red)}
board.map! do |x|
x.map! do |y|
y = colours.sample
end
end
return board
end
# Displays the splash screen, waits for input and then proceeds to the main
# menu
def splash_screen()
splash = ConsoleSplash.new()
splash.write_header("Flood It", "Daniel Marshall", "0.1.0",
{:nameFg=>:red})
splash.write_center(-5, "Copyright 2016-")
splash.write_top_pattern("/\\", {:fg=>:blue})
splash.write_bottom_pattern("\\/", {:fg=>:blue})
splash.write_vertical_pattern("|", {:fg=>:blue})
puts("\e[H\e[2J")
splash.splash
width = 14
height = 9
best_score = 0
gets
main_menu(width, height, best_score)
end
# Displays the main menu, waits for input and then performs an action based
# on the selected option
def main_menu(width, height, best_score)
puts("\e[H\e[2J")
puts "Main menu:"
puts "s = Start game"
puts "c = Change size"
puts "q = quit"
# Prints the best score achieved so far on the current board size
if best_score == 0
puts "No games played yet."
else
print "Best game: "
print best_score
puts " turns"
end
input = gets.to_s.chomp
case input
# Initalises the score and completion and starts a new game
when "s"
score = 0
completion = 0
board = get_board(width, height)
play_game(width, height, board, best_score, score, completion)
# Moves to the change size method
when "c"
change_size(width, height, best_score)
# Quits the program
when "q"
puts "Thank you for playing!"
exit
# If input is invalid, asks for input again
else
puts "Invalid input."
main_menu(width, height, best_score)
end
end
# Takes input for a new width and height and changes the board size, then
# returns to main menu
def change_size(width, height, best_score)
print "What is your new width? "
input = gets.chomp.to_i
width = input
print "What is your new height? "
input = gets.chomp.to_i
height = input
best_score = 0
main_menu(width, height, best_score)
end
# The main method for gameplay
def play_game(width, height, board, best_score, score, completion)
active = board[0][0]
counter = 0
puts("\e[H\e[2J")
# Prints the coloured tiles that make up the board using the
# randomised array
board.each do |x|
x.each do |y|
print " ".colorize(:background => y)
if y == active
counter = counter + 1
end
end
puts
end
# Calculates the completion percentage using the counter of
# coloured cells
completion = (counter * 100) / (width*height)
# If completion is 100%, the game is won! Print win message
# and change best score, then return to menu
if completion == 100
print "You won after "
print score
puts " turns"
gets
if score < best_score || best_score == 0
best_score = score
end
main_menu(width, height, best_score)
# Print turns and completion and ask for input
else
print "Number of turns: "
puts score
print "Current completion: "
print completion
puts "%"
puts board[0][0]
print "Choose a colour: "
input = gets.to_s.chomp
# Quit game if input is q
if input == "q"
main_menu(width, height, best_score)
# Pass the input to a separate method for updating the board,
# then continue playing the game
else
update(board, input)
score += 1
play_game(width, height, board, best_score, score, completion)
end
end
end
# Use the given input to update the top left cell, then continue to the
# recursive method which decides which other cells to update. (If the input
# is not a valid colour, this method uses up a turn but does nothing else.)
def update(board, input)
old_colour = board[0][0]
new_colour = nil
case input
when "r"
new_colour = :red
when "b"
new_colour = :blue
when "g"
new_colour = :green
when "c"
new_colour = :cyan
when "m"
new_colour = :magenta
when "y"
new_colour = :yellow
else
return
end
if old_colour == new_colour
return
end
update_cell(board, old_colour, new_colour, 0, 0)
end
# Recursive method - updates the current cell, then checks if all adjacent cells
# need updating (if they exist), and repeats the method using each applicable
# cell
def update_cell(board, old_colour, new_colour, x, y)
if x+1 <= board.length && y+1 <= board[0].length && y-1 >= -1 && x-1 >= -1
if board[x][y] != nil && board[x][y] == old_colour
board[x][y] = new_colour
update_cell(board, old_colour, new_colour, x+1, y)
update_cell(board, old_colour, new_colour, x-1, y)
update_cell(board, old_colour, new_colour, x, y+1)
update_cell(board, old_colour, new_colour, x, y-1)
else
return
end
end
end
splash_screen()