tttazures 0.0.4 → 0.0.9

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/board.rb +49 -0
  3. data/lib/board_printer_three_dim.rb +40 -0
  4. data/lib/board_printer_two_dim.rb +32 -0
  5. data/lib/computer_ai.rb +78 -0
  6. data/lib/config.rb +78 -0
  7. data/lib/console_ui.rb +107 -0
  8. data/lib/driver.rb +3 -0
  9. data/lib/game_controller.rb +76 -0
  10. data/lib/human_player.rb +17 -0
  11. data/lib/three_dimensional_board.rb +197 -0
  12. data/lib/two_dimensional_board.rb +67 -0
  13. data/spec/board_3x3_spec.rb +108 -0
  14. data/spec/board_3x3x3_spec.rb +173 -0
  15. data/spec/board_4x4_spec.rb +95 -0
  16. data/spec/board_5x5_spec.rb +74 -0
  17. data/spec/computer_ai_3x3_board_spec.rb +62 -0
  18. data/spec/computer_ai_spec.rb +10 -0
  19. data/spec/configurer_spec.rb +140 -0
  20. data/spec/console_ui_spec.rb +115 -0
  21. data/spec/coverage/assets/0.7.1/application.css +1110 -0
  22. data/spec/coverage/assets/0.7.1/application.js +626 -0
  23. data/spec/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  24. data/spec/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  25. data/spec/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  26. data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  27. data/spec/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  28. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  29. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  30. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  31. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  32. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  33. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  34. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  35. data/spec/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  36. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  37. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  38. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  39. data/spec/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  40. data/spec/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  41. data/spec/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  42. data/spec/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  43. data/spec/coverage/assets/0.7.1/favicon_green.png +0 -0
  44. data/spec/coverage/assets/0.7.1/favicon_red.png +0 -0
  45. data/spec/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  46. data/spec/coverage/assets/0.7.1/loading.gif +0 -0
  47. data/spec/coverage/assets/0.7.1/magnify.png +0 -0
  48. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  49. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  50. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  51. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  52. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  53. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  54. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  55. data/spec/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  56. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  57. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  58. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  59. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  60. data/spec/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  61. data/spec/coverage/index.html +72 -0
  62. data/spec/game_controller_spec.rb +50 -0
  63. data/spec/human_player_spec.rb +20 -0
  64. data/spec/long_tests.rb +265 -0
  65. data/spec/spec_helper.rb +4 -0
  66. metadata +121 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86905b2d2ffae64896bc07afeabeeac7943ba70f
4
- data.tar.gz: 44ae05f387b0a8ed9929112c2401dd075e4da34c
3
+ metadata.gz: 460e19f29c18852dacd3caa80532ca13dfad0420
4
+ data.tar.gz: f1219fe9ebdd295aebd4368b58d29a98346c9dbc
5
5
  SHA512:
6
- metadata.gz: 4e6467a7fc1a8feba19c11ba8c541337da577a8dad7635967ad9cbd318430279f6cc28e07518875cff39207a6b3d8008893f90804485662d6f1706bc0d31d44a
7
- data.tar.gz: f1f293fac35e578fc95ebbc979a3e582e5967403d7515302215e183d68780be65d8575e2b471cad40b2cc5f9b15e1c8b09a2c12a56deb71bc8d2b3945c0679fe
6
+ metadata.gz: a5cbc1431951539ce91812d3e4464d02972b66421b67cc62c5114583c9c9b5e2e6ade8751fb5d7857e498944b46a5f2705f7b7acd214264ec200f717d35ae50f
7
+ data.tar.gz: a80d5113273b3f26f936b14bdfc2ae1565738015a7c64624e12fde150ca23a4e25b9ee8bc4c7fddca9584bd0252e3b1ece363e34607fe2941db8a210fe374087
data/lib/board.rb ADDED
@@ -0,0 +1,49 @@
1
+ class Board
2
+
3
+ attr_reader :row_length
4
+
5
+ def get_print_results
6
+ #row length d because
7
+ #it is needed to show correct 2d version of @board_array array
8
+ [@board_array, @row_length]
9
+ end
10
+
11
+ def get_open_spots
12
+ open_spots = []
13
+ @board_array.each_index {|index| open_spots << index if @board_array[index] == :open}
14
+ open_spots
15
+ end
16
+
17
+ def remove_choice choice
18
+ @board_array[choice] = :open if valid_choice? choice
19
+ end
20
+
21
+ def record_choice choice, player
22
+ if valid_choice?(choice) && @board_array[choice] == :open
23
+ @board_array[choice] = player
24
+ return true
25
+ else return false end
26
+ end
27
+
28
+ def valid_choice? choice
29
+ choice = choice.to_i
30
+ if choice >= 0 && choice <= @board_array.length
31
+ return true else return false end
32
+ end
33
+
34
+
35
+
36
+ #deprecated, write tests for board_is_full?
37
+ def check_for_tie
38
+ if @board_array.include?(:open) then return :continue_game else return :tie end
39
+ end
40
+
41
+ def win_is_found a
42
+ a.size == 1 && !a.include?(:open)
43
+ end
44
+
45
+ def board_is_full?
46
+ !@board_array.include?(:open)
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ class BoardPrinterThreeDim
2
+
3
+ def initialize output= STDOUT
4
+ @output = output
5
+ end
6
+
7
+ def print print_results
8
+ board = print_results[0]
9
+ row_length = print_results[1].to_i
10
+
11
+ start_index = 0
12
+ row_length.times do
13
+ index = start_index
14
+ row_length.times do
15
+ row_length.times do
16
+ symbol = get_element_symbol board, index
17
+ if symbol.to_s.size == 1
18
+ @output.print " #{symbol} "
19
+ else
20
+ @output.print " #{symbol} "
21
+ end
22
+ index += 1
23
+ end
24
+ @output.print " "
25
+ index += 6
26
+ end
27
+ @output.puts
28
+ start_index += row_length
29
+ end
30
+ @output.puts
31
+ end
32
+
33
+ def get_element_symbol board_array, index
34
+ case board_array[index]
35
+ when :x then symbol = "X"
36
+ when :o then symbol = "O"
37
+ else symbol = index end
38
+ symbol
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ class BoardPrinterTwoDim
2
+
3
+ def initialize output= STDOUT
4
+ @output = output
5
+ end
6
+
7
+ def print print_results
8
+ board = print_results[0]
9
+ row_length = print_results[1]
10
+
11
+ board.to_enum.with_index.each do |value, index|
12
+ symbol = get_element_symbol board, index
13
+
14
+ if symbol.to_s.size == 1
15
+ @output.print " #{symbol}"
16
+ else
17
+ @output.print " #{symbol}"
18
+ end
19
+
20
+ @output.puts "" if (index+1) % row_length == 0 && (index+1) != (row_length * row_length)
21
+ end
22
+ @output.puts "\n \n"
23
+ end
24
+
25
+ def get_element_symbol board_array, index
26
+ case board_array[index]
27
+ when :x then symbol = "X"
28
+ when :o then symbol = "O"
29
+ else symbol = index end
30
+ symbol
31
+ end
32
+ end
@@ -0,0 +1,78 @@
1
+ class ComputerAI
2
+
3
+ MIN_ALPHA = -1.0/0
4
+ MAX_BETA = 1.0/0
5
+ TOP_DEPTH = 0
6
+
7
+ attr_reader :player, :threshold
8
+
9
+ def initialize player, threshold
10
+ @threshold = threshold
11
+ @player = player
12
+ end
13
+
14
+ def make_move board
15
+ update_depth_limit(board)
16
+ if use_mini_max? then best_options = mini_max_top(board, @player)
17
+ else best_options = make_random_move(board) end
18
+ choice = best_options.sample
19
+ board.record_choice(choice, @player)
20
+ choice
21
+ end
22
+
23
+ def mini_max_top board, player
24
+ best_moves = []
25
+ best_score = -1.0/0
26
+ open_moves = board.get_open_spots
27
+ open_moves.each do |move|
28
+ board.record_choice(move,player)
29
+ score = -mini_max(board, opponent(player), TOP_DEPTH+1, MIN_ALPHA, MAX_BETA)
30
+ board.remove_choice(move)
31
+ if score > best_score
32
+ best_score = score
33
+ best_moves.clear << move
34
+ elsif score == best_score
35
+ best_moves << move
36
+ end
37
+ end
38
+ best_moves
39
+ end
40
+
41
+ def mini_max board,player, depth, alpha, beta
42
+ if depth >= @depth_limit || alpha >= beta then return 0 end
43
+
44
+ if board.check_board_status == :tie
45
+ return 0
46
+ elsif board.check_board_status != :continue_game
47
+ return -(@depth_limit/depth)
48
+ end
49
+
50
+ open_moves = board.get_open_spots
51
+ open_moves.each do |move|
52
+ board.record_choice(move,player)
53
+ score = -mini_max(board, opponent(player), depth+1, -beta,-alpha)
54
+ board.remove_choice(move)
55
+ alpha = score if score > alpha
56
+ end
57
+ alpha
58
+ end
59
+
60
+ def update_depth_limit board
61
+ if board.get_open_spots.size > 18 then @depth_limit = 4
62
+ elsif board.get_open_spots.size > 14 then @depth_limit = 5
63
+ elsif board.get_open_spots.size > 8 then @depth_limit = 6
64
+ else @depth_limit = 7 end
65
+ end
66
+
67
+ def make_random_move board
68
+ board.get_open_spots
69
+ end
70
+
71
+ def use_mini_max?
72
+ if rand(100) < @threshold then true else false end
73
+ end
74
+
75
+ def opponent player
76
+ if player == :o then return :x else return :o end
77
+ end
78
+ end
data/lib/config.rb ADDED
@@ -0,0 +1,78 @@
1
+ require_relative './computer_ai'
2
+ require_relative './human_player'
3
+ require_relative './two_dimensional_board'
4
+ require_relative './three_dimensional_board'
5
+
6
+ class Configurer
7
+
8
+ def initialize console
9
+ @console = console
10
+ end
11
+
12
+ def get_board
13
+ choice = get_board_choice
14
+ case choice
15
+ when 0 then TwoDimensionalBoard.new 3
16
+ when 1 then TwoDimensionalBoard.new 4
17
+ when 2 then TwoDimensionalBoard.new 5
18
+ when 3 then ThreeDimensionalBoard.new 3
19
+ end
20
+ end
21
+
22
+ def get_players
23
+ user_input = @console.query_user_for_game_type
24
+ players = {}
25
+ case user_input
26
+ when 0
27
+ players[:player1] = HumanPlayer.new(:x, @console)
28
+ players[:player2] = HumanPlayer.new(:o, @console)
29
+ when 1
30
+ players[:player1] = HumanPlayer.new(:x, @console)
31
+ players[:player2] = set_ai_difficulty(:o)
32
+ when 2
33
+ players[:player1] = set_ai_difficulty(:o)
34
+ players[:player2] = HumanPlayer.new(:x, @console)
35
+ when 3
36
+ players[:player1] = set_ai_difficulty(:x)
37
+ players[:player2] = set_ai_difficulty(:o)
38
+ end
39
+ players
40
+ end
41
+
42
+ def set_ai_difficulty symbol
43
+ ai_difficulty_choice = get_ai_choice_from_user(symbol)
44
+ case ai_difficulty_choice
45
+ when 0 then ComputerAI.new(symbol, 10)
46
+ when 1 then ComputerAI.new(symbol, 50)
47
+ when 2 then ComputerAI.new(symbol, 100)
48
+ end
49
+ end
50
+
51
+ def get_board_choice
52
+ valid_choice = false
53
+ while valid_choice == false
54
+ choice = @console.query_user_for_board_type
55
+ if choice >= 0 && choice < 4 then valid_choice = true
56
+ else @console.print_user_input_error end
57
+ end
58
+ choice
59
+ end
60
+
61
+ def get_ai_choice_from_user symbol
62
+ valid_choice = false
63
+ while(!valid_choice)
64
+ choice = @console.query_user_for_ai_difficulty(symbol)
65
+ if choice < 3 && choice >= 0 then valid_choice = true end
66
+ end
67
+ choice
68
+ end
69
+
70
+ def get_board_printer board
71
+ if board.get_type == :two_dimensional_board
72
+ BoardPrinterTwoDim.new
73
+ elsif board.get_type == :three_dimensional_board
74
+ BoardPrinterThreeDim.new
75
+ end
76
+ end
77
+
78
+ end
data/lib/console_ui.rb ADDED
@@ -0,0 +1,107 @@
1
+ class ConsoleUI
2
+
3
+ def initialize output= STDOUT
4
+ @output = output
5
+ end
6
+
7
+ def query_user_for_choice user
8
+ @output.puts "User #{user}: Choose!"
9
+ receive_user_choice.to_i
10
+ end
11
+
12
+ def query_user_for_new_game
13
+ print_new_game_prompt
14
+ choice = receive_user_choice
15
+ return choice == "y" ? true : false
16
+ end
17
+
18
+ def receive_user_choice
19
+ begin
20
+ choice = gets.chomp.downcase
21
+ rescue Interrupt => e
22
+ @output.puts e
23
+ end
24
+ say_goodbye if choice == 'q'
25
+ return choice
26
+ end
27
+
28
+ def print_player_move move, player
29
+ puts "Player #{player.player} chose #{move}"
30
+ end
31
+
32
+ def respond_to_choice choice_accepted, choice
33
+ if choice_accepted then @output.puts "You Chose: #{choice}"
34
+ else print_user_input_error end
35
+ end
36
+
37
+ def query_user_for_board_type
38
+ print_board_options
39
+ receive_user_choice.to_i
40
+ end
41
+
42
+ def query_user_for_ai_difficulty symbol
43
+ print_ai_difficulty_options(symbol)
44
+ receive_user_choice.to_i
45
+ end
46
+
47
+ def query_user_for_game_type
48
+ valid_choice = false
49
+ while valid_choice == false
50
+ print_game_options
51
+ choice = receive_user_choice.to_i
52
+ if choice >= 0 && choice < 4 then valid_choice = true
53
+ else print_user_input_error end
54
+ end
55
+ choice
56
+ end
57
+
58
+ def print_board_options
59
+ @output.puts "What type of board size would you like to use?"
60
+ @output.puts " Choose 0 for 3x3 board"
61
+ @output.puts " Choose 1 for 4x4 board"
62
+ @output.puts " Choose 2 for 5x5 board"
63
+ @output.puts " Choose 3 for 3x3x3 board"
64
+ end
65
+
66
+ def print_ai_difficulty_options player
67
+ @output.puts "How difficult will Player #{player} AI be?"
68
+ @output.puts " Choose 0: AI is easy to beat"
69
+ @output.puts " Choose 1: AI is medium difficulty"
70
+ @output.puts " Choose 2: AI is unbeatable (except for 3x3x3)"
71
+ end
72
+
73
+ def print_game_options
74
+ @output.puts "Choose Game Type"
75
+ @output.puts " Choose 0 for Human v. Human"
76
+ @output.puts " Choose 1 for Human v. Computer, Human goes first"
77
+ @output.puts " Choose 2 for Human v. Computer, Computer goes first"
78
+ @output.puts " Choose 3 for Computer v. Computer"
79
+ end
80
+
81
+ def present_game_result game_result
82
+ if game_result == :tie then @output.puts "Game Over: Tie"
83
+ else @output.puts "Game Over. Player #{game_result} Wins" end
84
+ end
85
+
86
+ def greet_user
87
+ @output.puts "---Welcome to Tic Tac Toe---"
88
+ @output.puts "Press 'q' at any time to exit game"
89
+ end
90
+
91
+ def say_goodbye
92
+ @output.puts "Thanks for playing!"
93
+ exit
94
+ end
95
+
96
+ def print_user_input_error
97
+ @output.puts "Whoops! That choice wasn't valid, try again:"
98
+ end
99
+
100
+ def print_new_game_prompt
101
+ @output.puts "Would you like to start another game? Press 'Y' if yes. Press Any Other Key to Exit"
102
+ end
103
+
104
+ def print printString
105
+ @output.puts printString;
106
+ end
107
+ end
data/lib/driver.rb ADDED
@@ -0,0 +1,3 @@
1
+ require './game_controller'
2
+ controller = GameController.new
3
+ controller.run
@@ -0,0 +1,76 @@
1
+ require_relative './console_ui'
2
+ require_relative './computer_ai'
3
+ require_relative './human_player'
4
+ require_relative './two_dimensional_board'
5
+ require_relative './three_dimensional_board'
6
+ require_relative './board_printer_three_dim'
7
+ require_relative './board_printer_two_dim'
8
+ require_relative "./config"
9
+
10
+ class GameController
11
+
12
+ attr_reader :console, :ai
13
+
14
+ def initialize
15
+ @console = ConsoleUI.new
16
+ @config = Configurer.new(@console)
17
+ end
18
+
19
+ def run
20
+
21
+ @console.greet_user
22
+ new_game = true
23
+ while new_game
24
+
25
+ setup_game
26
+ player = @player1
27
+ while @board.check_board_status == :continue_game
28
+ display_board
29
+ move = player.make_move(@board)
30
+ @console.print_player_move(move,player)
31
+ player = opponent(player)
32
+ end
33
+
34
+ display_board
35
+ present_game_result
36
+ new_game = play_again?
37
+ end
38
+ end
39
+
40
+ def setup_game
41
+ set_players
42
+ @board = @config.get_board
43
+ @board_printer = @config.get_board_printer(@board)
44
+ end
45
+
46
+ def set_players
47
+ players = @config.get_players
48
+ @player1 = players[:player1]
49
+ @player2 = players[:player2]
50
+ end
51
+
52
+ def display_board
53
+ @board_printer.print(@board.get_print_results)
54
+ end
55
+
56
+ def present_game_result
57
+ @console.present_game_result(@board.check_board_status)
58
+ end
59
+
60
+ def play_again?
61
+ response = @console.query_user_for_new_game
62
+
63
+ if response then true
64
+ else
65
+ @console.say_goodbye
66
+ false
67
+ end
68
+ end
69
+
70
+ def opponent player
71
+ if player == @player1 then @player2 else @player1 end
72
+ end
73
+
74
+ end
75
+
76
+
@@ -0,0 +1,17 @@
1
+ class HumanPlayer
2
+
3
+ attr_reader :player
4
+
5
+ def initialize player, console
6
+ @console = console
7
+ @player = player
8
+ end
9
+
10
+ def make_move board
11
+ valid_choice = false
12
+ while !valid_choice
13
+ choice = @console.query_user_for_choice(@player)
14
+ valid_choice = board.record_choice(choice, @player)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,197 @@
1
+ require_relative "./board"
2
+
3
+ class ThreeDimensionalBoard < Board
4
+
5
+ def initialize size
6
+ @board_array = Array.new(size**3, :open)
7
+ @row_length = size
8
+ @row_length_squared = size**2
9
+ end
10
+
11
+ def get_print_results
12
+ #row length needed to show correct 2d version of @board_array array
13
+ [@board_array, 3]
14
+ end
15
+
16
+ def get_type
17
+ :three_dimensional_board
18
+ end
19
+
20
+ def check_board_status
21
+ result = :continue_game
22
+ if (column_result = check_column_win(@board_array)) != :continue_game
23
+ result = column_result
24
+ elsif (row_result = check_rows_for_win(@board_array)) != :continue_game
25
+ result = row_result
26
+ elsif (diag_result = check_diagonal_wins(@board_array)) != :continue_game
27
+ result = diag_result
28
+ elsif (tie_result = check_for_tie) != :continue_game
29
+ result = tie_result
30
+ end
31
+ return result
32
+ end
33
+
34
+ def check_column_win board
35
+ start_index = 0
36
+ @row_length.times do
37
+ @row_length.times do
38
+ if board[start_index] != :open
39
+ if board[start_index] == board[start_index + 3] && board[start_index+3] == board[start_index + 6]
40
+ return board[start_index]
41
+ end
42
+ end
43
+ start_index += 1
44
+ end
45
+ start_index += 6
46
+ end
47
+ return :continue_game
48
+ end
49
+
50
+ def check_rows_for_win board
51
+ if (result = check_left_right_row_for_win(board)) != :continue_game
52
+ return result
53
+ elsif (result = check_front_to_back_row_win(board)) != :continue_game
54
+ return result
55
+ else return :continue_game end
56
+ end
57
+
58
+ def check_left_right_row_for_win board
59
+ for row_number in 0...(@row_length**2)
60
+ row = get_row(row_number, board).uniq
61
+ return row.pop if win_is_found(row)
62
+ end
63
+ :continue_game
64
+ end
65
+
66
+ def get_row row_number, board
67
+ start_index = row_number * @row_length
68
+ board.slice(start_index, @row_length)
69
+ end
70
+
71
+ def get_front_back_row start_index, board
72
+ board.select.with_index{|x,i| x if (i-start_index) % (@row_length**2) == 0}
73
+ end
74
+
75
+ def check_front_to_back_row_win board
76
+ for row_number in 0..(@row_length**2)
77
+ row = get_front_back_row(row_number,board).uniq
78
+ return row.pop if win_is_found(row)
79
+ end
80
+ :continue_game
81
+ end
82
+
83
+ def check_diagonal_wins board
84
+ if (result = check_top_bottom_diagonal(board)) != :continue_game
85
+ return result
86
+ elsif (result = check_bottom_top_diagonal(board)) != :continue_game
87
+ return result
88
+ elsif (result = horizontal_left_right_diagonal_check(board)) != :continue_game
89
+ return result
90
+ elsif (result = horizontal_right_left_diagonal_check(board)) != :continue_game
91
+ return result
92
+ elsif (result = vertical_top_bottom_diagonal_check(board)) != :continue_game
93
+ return result
94
+ elsif (result = vertical_bottom_top_diagonal_check(board)) != :continue_game
95
+ return result
96
+ elsif (result = angled_through_center_diagonals_check(board)) != :continue_game
97
+ return result
98
+ else return :continue_game end
99
+ end
100
+
101
+
102
+
103
+ def check_top_bottom_diagonal board
104
+ for diag_number in 0...@row_length
105
+ index = diag_number*@row_length_squared
106
+ sub_board = board.slice(index, @row_length_squared)
107
+ diagonal = get_top_bottom_diagonal(index, sub_board).uniq
108
+ return diagonal.pop if win_is_found(diagonal)
109
+ end
110
+ :continue_game
111
+ end
112
+
113
+ def get_top_bottom_diagonal start_index, board
114
+ board.select.with_index {|x,i| x if i % (@row_length+1) == 0}
115
+ end
116
+
117
+ def check_bottom_top_diagonal board
118
+ index = 6
119
+ @row_length.times do
120
+ if board[index] != :open
121
+ if board[index] == board[index-2] && board[index-2] == board[index-4]
122
+ return board[index]
123
+ end
124
+ end
125
+ index += 9
126
+ end
127
+ return :continue_game
128
+ end
129
+
130
+ def horizontal_left_right_diagonal_check board
131
+ index = 0
132
+ @row_length.times do
133
+ if board[index] != :open
134
+ if board[index] == board[index+10] && board[index+10] == board[index+20]
135
+ return board[index]
136
+ end
137
+ end
138
+ index += 3
139
+ end
140
+ return :continue_game
141
+ end
142
+
143
+ def horizontal_right_left_diagonal_check board
144
+ index = 2
145
+ @row_length.times do
146
+ if board[index] != :open
147
+ if board[index] == board[index+8] && board[index+8] == board[index+16]
148
+ return board[index]
149
+ end
150
+ end
151
+ index += 3
152
+ end
153
+ return :continue_game
154
+ end
155
+
156
+ def vertical_top_bottom_diagonal_check board
157
+ index = 0
158
+ @row_length.times do
159
+ if board[index] != :open
160
+ if board[index] == board[index+12] && board[index+12] == board[index+24]
161
+ return board[index]
162
+ end
163
+ end
164
+ index += 1
165
+ end
166
+ return :continue_game
167
+ end
168
+
169
+ def vertical_bottom_top_diagonal_check board
170
+ index = 6
171
+ @row_length.times do
172
+ if board[index] != :open
173
+ if board[index] == board[index+6] && board[index+6] == board[index+12]
174
+ return board[index]
175
+ end
176
+ end
177
+ index += 1
178
+ end
179
+ return :continue_game
180
+ end
181
+
182
+ def angled_through_center_diagonals_check board
183
+ #scores diagonals starting at a front corner, angling through center,
184
+ #ending at back, opposite corner of cube
185
+ if board[0] != :open && board[0] == board[13] && board[13] == board[26]
186
+ return board[0]
187
+ elsif board[2] != :open && board[2] == board[13] && board[13] == board[24]
188
+ return board[2]
189
+ elsif board[6] != :open && board[6] == board[13] && board[13] == board[20]
190
+ return board[6]
191
+ elsif board[8] != :open && board[8] == board[13] && board[13] == board[18]
192
+ return board[8]
193
+ end
194
+ return :continue_game
195
+ end
196
+
197
+ end