# test/game_test.rb
require File.join(File.dirname(__FILE__), '..', 'lib', 'libttc')
require 'test/unit'

class GameTest < Test::Unit::TestCase

  def test_init
    assert_nothing_raised { Game.new(6,6,6,6,6) }
    assert_equal [], Game.new(6,6,6,6,6).history
  end


  def test_game_init
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []
  end


  def test_single_moves_1
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    assert_raise(InvalidMoveError) {game.apply_move!(moveA1A5, 'b')}

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA1A5, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []
  end

  def test_separate_moves
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA1A5, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A3, 'b')
    assert_equal game.history.length, 2
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []
  end



  def test_captures
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA1A5, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A5, 'b')
    assert_equal game.history.length, 2
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1
  end


  def test_no_captures_on_safe_spaces
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA2A4, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A4, 'b')
    assert_equal game.history.length, 2
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a4']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []
  end

  def test_move_after_captures
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA1A5, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A5, 'b')
    assert_equal game.history.length, 2
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveA2A4, 'a')
    assert_equal game.history.length, 3
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveB2A3, 'b')
    assert_equal game.history.length, 4
    assert_equal game.pieces['a1'].position, game.board.positions['a3']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1
  end


  def test_game
    game = Game.new(6,6,6,6,6)

    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceB2 = game.pieces['b2']

    posA  = game.board.positions['a']
    posB  = game.board.positions['b']
    posA3 = game.board.positions['a3']
    posA4 = game.board.positions['a4']
    posA5 = game.board.positions['a5']

    moveA2A  = Move.new(pieceA2, posA , true)
    moveA1A3 = Move.new(pieceA1, posA3)
    moveA1A5 = Move.new(pieceA1, posA5)
    moveA2A4 = Move.new(pieceA2, posA4)
    moveA2A3 = Move.new(pieceA2, posA3)
    moveB2A5 = Move.new(pieceB2, posA5)
    moveB2A3 = Move.new(pieceB2, posA3)
    moveB2A4 = Move.new(pieceB2, posA4)

    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA1A5, 'a')
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['b']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A3, 'b')
    assert_equal game.history.length, 2
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA2A4, 'a')
    assert_equal game.history.length, 3
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, false
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveB2A5, 'b')
    assert_equal game.history.length, 4
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    assert_raise(InvalidMoveError) {game.apply_move!(moveA1A3, 'a')}
    assert_equal game.history.length, 4
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveA2A3, 'a')
    assert_equal game.history.length, 5
    assert_equal game.pieces['a1'].position, game.board.positions['a5']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a3']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a5']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveB2A4, 'b')
    assert_equal game.history.length, 6
    assert_equal game.pieces['a1'].position, game.board.positions['a4']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a3']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a4']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveA2A4, 'a')
    assert_equal game.history.length, 7
    assert_equal game.pieces['a1'].position, game.board.positions['a4']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a4']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveB2A3, 'b')
    assert_equal game.history.length, 8
    assert_equal game.pieces['a1'].position, game.board.positions['a3']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a4']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, false
    assert       game.pieces['b2'].contains.include?(pieceA1)
    assert_equal game.pieces['b2'].contains.length, 1

    game.apply_move!(moveA2A3, 'a')
    assert_equal game.history.length, 9
    assert_equal game.pieces['a1'].position, game.board.positions['a3']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a3']
    assert_equal game.pieces['a2'].captured, false
    assert       game.pieces['a2'].contains.include?(pieceA1)
    assert       game.pieces['a2'].contains.include?(pieceB2)
    assert_equal game.pieces['a2'].contains.length, 2
    assert_equal game.pieces['b2'].position, game.board.positions['a3']
    assert_equal game.pieces['b2'].captured, true
    assert_equal game.pieces['b2'].contains, []

    game.apply_move!(moveA2A, 'a')
    assert_equal game.history.length, 10
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['b2'].position, game.board.positions['a']
    assert_equal game.pieces['b2'].captured, true
    assert_equal game.pieces['b2'].contains, []
  end

  def test_apply_moves!
    game = Game.new(3)
    move_set = ['A1 A2', 'C1 C2', 'E1 E2']
    assert_nothing_raised { move_set.collect { |m| m.to_move(game) } }
    move_set_m = move_set.collect { |m| m.to_move(game) }
    assert_nothing_raised { game.apply_moves! move_set_m }
  end
  
  def test_eliminations
    game = Game.new(3, 6, 6, 6, 2)
  
    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceC1 = game.pieces['c1']
    pieceC2 = game.pieces['c2']
    pieceE1 = game.pieces['e1']
    pieceE2 = game.pieces['e2']

    posAC5 = game.board.positions['ac5']
    posBC5 = game.board.positions['bc5']
    posCC5 = game.board.positions['cc5']
    posEC5 = game.board.positions['ec5']
    posAC6 = game.board.positions['ac6']

    move_set1 = ['A1 AC5', 'A2 AC5', 'A1 AC6', 
      'C1 CC5', 'C2 CC5', 'C1 AC6']  # A1 now captured by C1
    move_set2 = ['E1 EC5', 'E2 EC5', 'E1 AC6'] # C1+A1 now caputred by E1
    move_set3 = ['A2 AC6'] # E1+C1+A1 captured by A2
    move_set4 = ['C2 AC6'] # A2+E1+C1+A1 captured by C2.  Player A now eliminated
    move_set5 = ['E2 BC5'] 
    move_set6 = ['C2 BC5'] # C2 (plus stack) captures E2.  Player E now eliminated
    
    assert_equal [], game.history
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['c']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['c']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'

    game.apply_moves! move_set1.collect {|m| m.to_move(game)}
    assert_equal game.history.length, 6
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, false
    assert       game.pieces['c1'].contains.include?(pieceA1) 
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'e'

    game.apply_moves! move_set2.collect {|m| m.to_move(game)}
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, false
    assert       game.pieces['e1'].contains.include?(pieceA1) 
    assert       game.pieces['e1'].contains.include?(pieceC1) 
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'

    game.apply_moves! move_set3.collect {|m| m.to_move(game)}
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac6']
    assert_equal game.pieces['a2'].captured, false
    assert       game.pieces['a2'].contains.include?(pieceA1) 
    assert       game.pieces['a2'].contains.include?(pieceC1) 
    assert       game.pieces['a2'].contains.include?(pieceE1) 
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, true
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'c'

    game.apply_moves! move_set4.collect {|m| m.to_move(game)}
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac6']
    assert_equal game.pieces['a2'].captured, true
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['ac6']
    assert_equal game.pieces['c2'].captured, false
    assert       game.pieces['c2'].contains.include?(pieceA1) 
    assert       game.pieces['c2'].contains.include?(pieceA2) 
    assert       game.pieces['c2'].contains.include?(pieceC1) 
    assert       game.pieces['c2'].contains.include?(pieceE1) 
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, true
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'e'

    game.apply_moves! move_set5.collect {|m| m.to_move(game)}
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac6']
    assert_equal game.pieces['a2'].captured, true
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['ac6']
    assert_equal game.pieces['c2'].captured, false
    assert       game.pieces['c2'].contains.include?(pieceA1) 
    assert       game.pieces['c2'].contains.include?(pieceA2) 
    assert       game.pieces['c2'].contains.include?(pieceC1) 
    assert       game.pieces['c2'].contains.include?(pieceE1) 
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, true
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['bc5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'c'
    
    assert_raise (GameWonNotice) { game.apply_moves! move_set6.collect {|m| m.to_move(game)} }  
  end
  
  def test_undo_move!
    game = Game.new(3)
  
    pieceA1 = game.pieces['a1']
    pieceA2 = game.pieces['a2']
    pieceC1 = game.pieces['c1']
    pieceC2 = game.pieces['c2']
    pieceE1 = game.pieces['e1']
    pieceE2 = game.pieces['e2']
    
    assert_equal [], game.history
    assert_equal game.pieces['a1'], pieceA1
    assert_equal game.pieces['a2'], pieceA2
    assert_equal game.pieces['c1'], pieceC1
    assert_equal game.pieces['c2'], pieceC2
    assert_equal game.pieces['e1'], pieceE1
    assert_equal game.pieces['e2'], pieceE2
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['c']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['c']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'
    
    game.undo_move!
    assert_equal [], game.history
    assert_equal game.pieces['a1'], pieceA1
    assert_equal game.pieces['a2'], pieceA2
    assert_equal game.pieces['c1'], pieceC1
    assert_equal game.pieces['c2'], pieceC2
    assert_equal game.pieces['e1'], pieceE1
    assert_equal game.pieces['e2'], pieceE2
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['c']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['c']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'

    game.apply_moves! ['A1 A3'].collect { |m| m.to_move(game) }
    assert_equal game.history.length, 1
    assert_equal game.pieces['a1'], pieceA1
    assert_equal game.pieces['a2'], pieceA2
    assert_equal game.pieces['c1'], pieceC1
    assert_equal game.pieces['c2'], pieceC2
    assert_equal game.pieces['e1'], pieceE1
    assert_equal game.pieces['e2'], pieceE2
    assert_equal game.pieces['a1'].position, game.board.positions['a3']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['c']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['c']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'c'

    game.undo_move!
    assert_equal [], game.history
    assert_equal game.pieces['a1'], pieceA1
    assert_equal game.pieces['a2'], pieceA2
    assert_equal game.pieces['c1'], pieceC1
    assert_equal game.pieces['c2'], pieceC2
    assert_equal game.pieces['e1'], pieceE1
    assert_equal game.pieces['e2'], pieceE2
    assert_equal game.pieces['a1'].position, game.board.positions['a']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['a']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['c']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['c']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'

    move_set1 = ['A1 AC5', 'A2 AC5', 'A1 AC6', 
      'C1 CC5', 'C2 CC5', 'C1 AC6']  # A1 now captured by C1
    move_set1a = ['C1 AC6']
    move_set2 = ['E1 EC5', 'E2 EC5', 'E1 AC6'] # C1+A1 now caputred by E1
    move_set2a = ['E1 AC6']

    game.apply_moves! move_set1.collect {|m| m.to_move(game)}
    assert_equal game.history.length, 6
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, false
    assert       game.pieces['c1'].contains.include?(pieceA1) 
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'e'

    game.undo_move!
    assert_equal game.history.length, 5
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, false
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['cc5']
    assert_equal game.pieces['c1'].captured, false
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'c'

    game.apply_moves! move_set1a.collect {|m| m.to_move(game)}
    assert_equal game.history.length, 6
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, false
    assert       game.pieces['c1'].contains.include?(pieceA1) 
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['e']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['e']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'e'
        
    game.apply_moves! move_set2.collect {|m| m.to_move(game)}
    assert_equal game.history.length, 9
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, false
    assert       game.pieces['e1'].contains.include?(pieceA1) 
    assert       game.pieces['e1'].contains.include?(pieceC1) 
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'

    game.undo_move!
    assert_equal game.history.length, 8
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].captured, false
    assert       game.pieces['c1'].contains.include?(pieceA1) 

    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['ec5']
    assert_equal game.pieces['e1'].captured, false
    assert_equal game.pieces['e1'].contains, []
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'e'

        assert_equal game.pieces['c1'].position, game.pieces['a1'].position
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']

    
    game.apply_moves! move_set2a.collect {|m| m.to_move(game)}
    assert_equal game.history.length, 9
    assert_equal game.pieces['a1'].position, game.board.positions['ac6']
    assert_equal game.pieces['a1'].captured, true
    assert_equal game.pieces['a1'].contains, []
    assert_equal game.pieces['a2'].position, game.board.positions['ac5']
    assert_equal game.pieces['a2'].captured, false
    assert_equal game.pieces['a2'].contains, []
    assert_equal game.pieces['c1'].position, game.board.positions['ac6']
    assert_equal game.pieces['c1'].captured, true
    assert_equal game.pieces['c1'].contains, []
    assert_equal game.pieces['c2'].position, game.board.positions['cc5']
    assert_equal game.pieces['c2'].captured, false
    assert_equal game.pieces['c2'].contains, []
    assert_equal game.pieces['e1'].position, game.board.positions['ac6']
    assert_equal game.pieces['e1'].captured, false
    assert       game.pieces['e1'].contains.include?(pieceA1) 
    assert       game.pieces['e1'].contains.include?(pieceC1) 
    assert_equal game.pieces['e2'].position, game.board.positions['ec5']
    assert_equal game.pieces['e2'].captured, false
    assert_equal game.pieces['e2'].contains, []
    assert_equal game.current_player, 'a'
        
  end
end