summaryrefslogtreecommitdiff
path: root/bindings/ruby/quackle_runner.rb
blob: d466cfc6dd97e512ffd3ef577df62bdf3a7c97d1 (plain)
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
require_relative 'quackle'

# Some higher-level functions over the quackle bindings.

module Quackle
  PLAYER_TYPES = {
    speedy: "Speedy Player",
    championship: "Championship Player",
    championship_20s: "Twenty Second Championship Player",
    championship_5m: "Five Minute Championship Player",
  }

  module GCGUtils
    def self.load_game(path)
      gamereader = GCGIO.new
      gamePath = Util.stdStringToQString(path)
      gamereader.read(gamePath, Logania::MaintainBoardPreparation)
    end
  end

  module RunnerUtils
    def initialize_dm(lexicon, alphabet, datadir)
      # Set up the data manager
      dm = DataManager.new
      dm.setComputerPlayers(ComputerPlayerCollection.fullCollection)
      dm.setBackupLexicon(lexicon)
      dm.setAppDataDirectory(datadir)

      # Set up the alphabet
      abc = AlphabetParameters.findAlphabetFile(alphabet)
      abc2 = Util.stdStringToQString(abc) #convert to qstring
      fa = FlexibleAlphabetParameters.new

      fail unless fa.load(abc2)
      dm.setAlphabetParameters(fa)

      # Set up the board
      board = BoardParameters.new
      dm.setBoardParameters(board)

      # Find the lexicon
      dawg = LexiconParameters.findDictionaryFile(lexicon + '.dawg')
      gaddag = LexiconParameters.findDictionaryFile(lexicon + '.gaddag')
      dm.lexiconParameters.loadDawg(dawg)
      dm.lexiconParameters.loadGaddag(gaddag)

      dm.strategyParameters.init(lexicon)
      return dm
    end

    def computer_player(type)
      name = PLAYER_TYPES[type]
      if name
        player, found = @dm.computerPlayers.playerForName(name)
        if not found
          raise NameError("Could not initialize computer player #{name}")
        end
        player.computerPlayer
      else
        raise ArgumentError("Unknown computer player: #{type}")
      end
    end
  end

  class AIRunner
    include RunnerUtils

    attr_accessor :dm, :game, :players

    def initialize(lexicon:, alphabet:, datadir:, random_seed: nil)
      @dm = initialize_dm(lexicon, alphabet, datadir)
      @dm.seedRandomNumbers(random_seed) if random_seed
    end

    def init_game(players)
      @game = Game.new
      @players = PlayerList.new
      players.each_with_index do |(name, type), i|
        player = Player::new(name, Player::ComputerPlayerType, i)
        player.setComputerPlayer(computer_player(type))
        @players << player
      end

      game.setPlayers(@players)
      game.associateKnownComputerPlayers
      game.addPosition
    end

    def current_position
      game.currentPosition
    end

    def current_player
      current_position.currentPlayer
    end

    def board
      current_position.board
    end

    def make_move
      game.haveComputerPlay
    end

    def game_over?
      current_position.gameOver
    end
  end

end