ang_ttt_gem 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,28 +2,26 @@ require "scoring"
2
2
  require "board"
3
3
 
4
4
  class Ai
5
-
5
+
6
6
  def initialize(player, board)
7
7
  @board = board
8
8
  @scoring = Scoring.new
9
9
  @max_mark = player.mark
10
10
  end
11
-
11
+
12
12
  def find_opponent_mark
13
13
  state = @board.current_state
14
- min_mark = state.reject {|c| c =~ /^#{@max_mark}|\s{1}$/ }
15
- @min_mark = min_mark[0]
14
+ @min_mark = state.reject {|c| c =~ /^#{@max_mark}|\s{1}$/ }.first
16
15
  end
17
-
16
+
18
17
  def select_optimal_start_move
19
- start_moves = [0, 2, 4, 6, 8]
20
- best_move = start_moves.sample
18
+ [0, 2, 4, 6, 8].sample
21
19
  end
22
-
20
+
23
21
  def random_move
24
- move = @board.available_spaces.sample
22
+ @board.available_spaces.sample
25
23
  end
26
-
24
+
27
25
  def find_best_move
28
26
  if @board.available_spaces.count == 9
29
27
  best_move = select_optimal_start_move
@@ -34,7 +32,7 @@ class Ai
34
32
  end
35
33
  best_move
36
34
  end
37
-
35
+
38
36
  def max_move
39
37
  best_move = nil
40
38
  best_score = nil
@@ -53,7 +51,7 @@ class Ai
53
51
  end
54
52
  return best_move, best_score
55
53
  end
56
-
54
+
57
55
  def min_move
58
56
  best_move = nil
59
57
  best_score = nil
@@ -72,11 +70,11 @@ class Ai
72
70
  end
73
71
  return best_move, best_score
74
72
  end
75
-
73
+
76
74
  def state_is_terminal?
77
75
  @scoring.winner?(@board) || @scoring.draw?(@board)
78
76
  end
79
-
77
+
80
78
  def evaluate_the_board
81
79
  decision = nil
82
80
  decision = 1 if @scoring.winner?(@board) && @scoring.winning_mark(@board) == @max_mark
@@ -1,64 +1,64 @@
1
1
  class Board
2
-
2
+
3
3
  def initialize
4
4
  @cells = Array.new(9) {" "}
5
5
  end
6
-
6
+
7
7
  def get(cell_number)
8
8
  @cells[cell_number]
9
9
  end
10
-
10
+
11
11
  def set(cell_number, mark)
12
12
  @cells[cell_number] = mark
13
13
  end
14
-
14
+
15
15
  def undo_move(cell_number)
16
16
  @cells[cell_number] = " "
17
17
  end
18
-
18
+
19
19
  def available_spaces
20
20
  available_spaces = @cells.each_with_index.select { |i, idx| i =~ / / }
21
21
  available_spaces = available_spaces.map{|i| i[1] }
22
22
  available_spaces
23
23
  end
24
-
24
+
25
25
  def cell_occupied?(cell_number)
26
26
  get(cell_number.to_i - 1) != " "
27
27
  end
28
-
28
+
29
29
  def current_state
30
30
  current_state = @cells.map {|c| c}
31
31
  end
32
-
32
+
33
33
  def clear_all_spaces
34
34
  mark = " "
35
35
  @cells.each_with_index do |cell, index|
36
36
  set(index, mark)
37
37
  end
38
38
  end
39
-
39
+
40
40
  def rows
41
41
  [ @cells[0..2],
42
42
  @cells[3..5],
43
43
  @cells[6..8] ]
44
44
  end
45
-
45
+
46
46
  def columns
47
47
  rows.transpose
48
48
  end
49
-
49
+
50
50
  def diagonal_forward
51
51
  [ @cells[2],
52
52
  @cells[4],
53
53
  @cells[6] ]
54
54
  end
55
-
55
+
56
56
  def diagonal_back
57
57
  [ @cells[0],
58
58
  @cells[4],
59
59
  @cells[8] ]
60
60
  end
61
-
61
+
62
62
  def possible_winning_combinations
63
63
  possible_winning_combinations = []
64
64
  rows.collect{|row| possible_winning_combinations << row }
@@ -3,13 +3,13 @@ require "ai"
3
3
  require "board"
4
4
 
5
5
  class ComputerPlayer < Player
6
-
6
+
7
7
  attr_accessor :ai
8
-
8
+
9
9
  def initialize(mark)
10
10
  self.set_mark(mark)
11
11
  end
12
-
12
+
13
13
  def get_move(board)
14
14
  ai = Ai.new(self, board)
15
15
  cell_number = ai.find_best_move
@@ -5,33 +5,33 @@ require "human_player"
5
5
  require "computer_player"
6
6
 
7
7
  class Game
8
-
8
+
9
9
  attr_reader :players, :board
10
-
10
+
11
11
  def initialize
12
12
  @board = Board.new
13
13
  @scoring = Scoring.new
14
14
  @validate = Validate.new
15
15
  @players = []
16
16
  end
17
-
17
+
18
18
  def create_computer_player(mark)
19
19
  @players << ComputerPlayer.new(mark)
20
20
  end
21
-
21
+
22
22
  def create_human_player(mark)
23
23
  @players << HumanPlayer.new(mark)
24
24
  end
25
-
25
+
26
26
  def get_player_move(player)
27
27
  index = player - 1
28
28
  @players[index].get_move(@board)
29
29
  end
30
-
30
+
31
31
  def move_valid?(move)
32
32
  (0..8).include?(move)
33
33
  end
34
-
34
+
35
35
  def make_move_player(player, move)
36
36
  index = player - 1
37
37
  mark = @players[index].mark
@@ -39,28 +39,21 @@ class Game
39
39
  @board.set(move, mark)
40
40
  prepare_display_state
41
41
  end
42
-
42
+
43
43
  def square_taken?(cell_number)
44
44
  @board.cell_occupied?(cell_number)
45
45
  end
46
-
46
+
47
47
  def prepare_display_state
48
- board_display_state = []
49
- current_state = @board.current_state
50
- cell_numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
51
- index = 0
52
- current_state.each do |cell|
53
- board_display_state << cell_numbers[index] if cell == " "
54
- board_display_state << current_state[index] unless cell == " "
55
- index += 1
48
+ @board.current_state.each_with_index.map do |cell, index|
49
+ cell == " " ? (index + 1).to_s : cell
56
50
  end
57
- board_display_state
58
51
  end
59
-
52
+
60
53
  def is_over?
61
54
  @scoring.winner?(@board) || @scoring.draw?(@board)
62
55
  end
63
-
56
+
64
57
  def result
65
58
  message_key = :draw
66
59
  @players.each_with_index do |player, i|
@@ -3,11 +3,11 @@ require "validate"
3
3
  require "board"
4
4
 
5
5
  class HumanPlayer < Player
6
-
6
+
7
7
  def initialize(mark)
8
8
  self.set_mark(mark)
9
9
  end
10
-
10
+
11
11
  def get_move(board)
12
12
  return false
13
13
  end
@@ -1,25 +1,25 @@
1
1
  class Message
2
-
2
+
3
3
  def initialize
4
-
4
+
5
5
  @message = {
6
- welcome: "Welcome to Tic Tac Toe! You will create 2 players. The first player you create will go first.\n",
7
- create_player: "Create a player.\n",
8
- determine_player_type: "Do you want the player to be human or computer? (H/C)\n",
9
- select_player_mark: "Please select a single letter to represent the player.\n",
10
- invalid_selection: "That is an invalid selection, please make a valid selection.\n",
11
- select_square: "Please select an open square.\n",
12
- player_1_win: "Player 1 is the winner!\n",
13
- player_2_win: "Player 2 is the winner!\n",
14
- draw: "It's a draw.\n",
15
- play_again?: "Would you like to play again? (Y/N)\n",
6
+ welcome: "Welcome to Tic Tac Toe! You will create 2 players. The first player you create will go first.",
7
+ create_player: "Create a player.",
8
+ determine_player_type: "Do you want the player to be human or computer? (H/C)",
9
+ select_player_mark: "Please select a single letter to represent the player.",
10
+ invalid_selection: "That is an invalid selection, please make a valid selection.",
11
+ select_square: "Please select an open square.",
12
+ player_1_win: "Player 1 is the winner!",
13
+ player_2_win: "Player 2 is the winner!",
14
+ draw: "It's a draw.",
15
+ play_again?: "Would you like to play again? (Y/N)",
16
16
  }
17
17
  end
18
-
18
+
19
19
  def passed(*keys)
20
20
  message = String.new
21
21
  keys.each do |key|
22
- message << @message[key]
22
+ message << @message[key] + "\n"
23
23
  end
24
24
  message
25
25
  end
@@ -1,5 +1,5 @@
1
1
  class Player
2
-
2
+
3
3
  def set_mark(mark)
4
4
  @mark = mark
5
5
  end
@@ -1,7 +1,7 @@
1
1
  require "board"
2
2
 
3
3
  class Scoring
4
-
4
+
5
5
  def winner?(board)
6
6
  winner = false
7
7
  board.possible_winning_combinations.each do |combo|
@@ -11,7 +11,7 @@ class Scoring
11
11
  end
12
12
  winner
13
13
  end
14
-
14
+
15
15
  def winning_mark(board)
16
16
  board.possible_winning_combinations.each do |combo|
17
17
  if combo.uniq.length == 1 && combo[0] != " "
@@ -19,7 +19,7 @@ class Scoring
19
19
  end
20
20
  end
21
21
  end
22
-
22
+
23
23
  def draw?(board)
24
24
  winner?(board) == false && board.available_spaces.count == 0
25
25
  end
@@ -1,10 +1,10 @@
1
1
  class Validate
2
-
2
+
3
3
  def player_input(input)
4
4
  return false unless input =~ /[Hh,Cc]/
5
5
  return true
6
6
  end
7
-
7
+
8
8
  def mark_input(input)
9
9
  return false unless input =~ /[a-zA-Z]/
10
10
  return true
@@ -14,7 +14,7 @@ class Validate
14
14
  return false unless input =~ /[1-9]/
15
15
  return true
16
16
  end
17
-
17
+
18
18
  def play_again_input(input)
19
19
  return false unless input =~ /[Nn,Yy]/
20
20
  return true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ang_ttt_gem
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: