summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/Makefile56
-rw-r--r--bindings/go/quackle.go6
-rw-r--r--bindings/lua/test_selfplay.lua90
-rw-r--r--bindings/python/test1_position.py78
-rw-r--r--bindings/python/test2_selfplay.py84
-rw-r--r--bindings/quackle.i111
-rw-r--r--quackleio/gcgio.cpp18
-rw-r--r--quackleio/gcgio.h1
8 files changed, 444 insertions, 0 deletions
diff --git a/bindings/Makefile b/bindings/Makefile
new file mode 100644
index 0000000..9cdb6a3
--- /dev/null
+++ b/bindings/Makefile
@@ -0,0 +1,56 @@
+CC=g++
+
+QTFLAGS := $(shell pkg-config QtCore --cflags)
+QTLIBS := $(shell pkg-config QtCore --libs)
+PYTHONFLAGS := $(shell pkg-config python2 --cflags)
+PHPFLAGS := $(shell php-config --includes)
+PHPLIBS := $(shell php-config --libs)
+LUAFLAGS := $(shell pkg-config lua5.1 --cflags)
+
+INCLUDES=-I..
+QUACKLELIBS=../lib/release/libquackle.a ../quackleio/lib/release/libquackleio.a
+
+php/quackle_wrap.cxx:
+ @test -d php || mkdir php
+ swig -c++ -o $@ $(INCLUDES) $(QTFLAGS) -php quackle.i
+
+php/quackle_wrap.o: php/quackle_wrap.cxx
+ $(CC) -std=c++11 -fPIC $(QTFLAGS) $(PHPFLAGS) $(PHPLIBS) $(INCLUDES) -c $< -o $@
+
+php: php/quackle_wrap.o
+ $(CC) -std=c++11 -shared -Wl,--whole-archive $(QUACKLELIBS) -Wl,--no-whole-archive $(QTLIBS) $< -o php/quackle.so
+
+python/quackle_wrap.cxx:
+ @test -d python || mkdir python
+ swig -c++ -o $@ $(INCLUDES) $(QTFLAGS) -python quackle.i
+
+python/quackle_wrap.o: python/quackle_wrap.cxx
+ $(CC) -std=c++11 -fPIC $(QTFLAGS) $(PYTHONFLAGS) $(INCLUDES) -c $< -o $@
+
+python: python/quackle_wrap.o
+ $(CC) -std=c++11 -shared -Wl,--whole-archive $(QUACKLELIBS) -Wl,--no-whole-archive $(QTLIBS) $< -o python/_quackle.so
+
+go:
+ ln -sf ../quackle.i go/quackle.swigcxx
+ go build ./go/...
+
+lua/quackle_wrap.cxx:
+ @test -d lua || mkdir lua
+ swig -c++ -o $@ $(INCLUDES) $(QTFLAGS) -lua quackle.i
+
+lua/quackle_wrap.o: lua/quackle_wrap.cxx
+ $(CC) -std=c++11 -fPIC $(LUAFLAGS) $(QTFLAGS) $(INCLUDES) -c $< -o $@
+
+lua: lua/quackle_wrap.o
+ $(CC) -std=c++11 -shared $(LUAFLAGS) -Wl,--whole-archive $(QUACKLELIBS) -Wl,--no-whole-archive $(QTLIBS) $< -o lua/quackle.so
+
+.PHONY: clean go
+
+clean:
+ -rm -rf python/quackle.py
+ -rm -rf php/*php*
+ -rm -rf */*_wrap.cxx
+ -rm -rf */*.o
+ -rm -rf */*.so
+ -rm -rf */*.pyc
+ -rm -rf go/quackle.swigcxx
diff --git a/bindings/go/quackle.go b/bindings/go/quackle.go
new file mode 100644
index 0000000..6c40a84
--- /dev/null
+++ b/bindings/go/quackle.go
@@ -0,0 +1,6 @@
+package quackle
+
+// #cgo CXXFLAGS: -I../..
+// #cgo pkg-config: QtCore
+// #cgo LDFLAGS: -L${SRCDIR}/../../lib/release -L${SRCDIR}/../../quackleio/lib/release -lquackle -lquackleio -lQtCore
+import "C"
diff --git a/bindings/lua/test_selfplay.lua b/bindings/lua/test_selfplay.lua
new file mode 100644
index 0000000..9209f52
--- /dev/null
+++ b/bindings/lua/test_selfplay.lua
@@ -0,0 +1,90 @@
+require 'quackle'
+
+function startUp(lexicon, alphabet, datadir)
+
+ local lexicon = lexicon or 'twl06'
+ local alphabet = alphabet or 'english'
+ local datadir = datadir or '../../data'
+
+ -- Set up the data manager
+ local dm = quackle.DataManager()
+ dm:setComputerPlayers(quackle.ComputerPlayerCollection.fullCollection())
+ dm:setBackupLexicon(lexicon)
+ dm:setAppDataDirectory(datadir)
+
+ -- Set up the alphabet
+ local abc = quackle.AlphabetParameters.findAlphabetFile(alphabet)
+ local abc2 = quackle.Util.stdStringToQString(abc) --convert to qstring
+ local fa = quackle.FlexibleAlphabetParameters()
+
+ assert(fa:load(abc2))
+ dm:setAlphabetParameters(fa)
+
+ -- Set up the board
+ local board = quackle.BoardParameters()
+ dm:setBoardParameters(board)
+
+ -- Find the lexicon
+ local dawg = quackle.LexiconParameters.findDictionaryFile(lexicon .. '.dawg')
+ local gaddag = quackle.LexiconParameters.findDictionaryFile(lexicon .. '.gaddag')
+ dm:lexiconParameters():loadDawg(dawg)
+ dm:lexiconParameters():loadGaddag(gaddag)
+
+ dm:strategyParameters():initialize(lexicon)
+ return dm
+
+end
+
+
+function getComputerPlayer(dm, name)
+
+ local name = name or 'Speedy Player'
+
+ local player, found = dm:computerPlayers():playerForName(name)
+ assert(found)
+ player = player:computerPlayer()
+
+ return player
+
+end
+
+dm = startUp()
+
+p1 = getComputerPlayer(dm)
+p2 = getComputerPlayer(dm)
+
+-- Create computer players
+player1 = quackle.Player('Compy1', quackle.Player.ComputerPlayerType, 0)
+player1:setComputerPlayer(p1)
+print(player1:name())
+
+player2 = quackle.Player('Compy2', quackle.Player.ComputerPlayerType, 1)
+player2:setComputerPlayer(p2)
+print(player2:name())
+
+dm:seedRandomNumbers(42)
+
+game = quackle.Game()
+players = quackle.PlayerList()
+
+players:push_back(player1)
+players:push_back(player2)
+
+game:setPlayers(players)
+game:associateKnownComputerPlayers()
+game:addPosition()
+
+for i=1, 50 do
+ if game:currentPosition():gameOver() then
+ print "GAME OVER"
+ break
+ end
+
+ player = game:currentPosition():currentPlayer()
+ move = game:haveComputerPlay()
+ --print("Player: " .. player:name())
+ print("Rack : " .. player:rack():toString())
+ print('Move: ' .. move:toString())
+ print('Board: \n' .. game:currentPosition():board():toString())
+
+end
diff --git a/bindings/python/test1_position.py b/bindings/python/test1_position.py
new file mode 100644
index 0000000..e04081a
--- /dev/null
+++ b/bindings/python/test1_position.py
@@ -0,0 +1,78 @@
+# coding: utf-8
+
+import quackle
+
+def startUp(lexicon='twl06',
+ alphabet='english',
+ datadir='../../data'):
+
+ # Set up the data manager
+ dm = quackle.DataManager()
+ dm.setComputerPlayers(quackle.ComputerPlayerCollection.fullCollection())
+ dm.setBackupLexicon(lexicon)
+ dm.setAppDataDirectory(datadir)
+
+ # Set up the alphabet
+ abc = quackle.AlphabetParameters.findAlphabetFile(alphabet)
+ abc2 = quackle.Util.stdStringToQString(abc) #convert to qstring
+ fa = quackle.FlexibleAlphabetParameters()
+
+ assert fa.load(abc2)
+ dm.setAlphabetParameters(fa)
+
+ # Set up the board
+ board = quackle.BoardParameters()
+ dm.setBoardParameters(board)
+
+ # Find the lexicon
+ dawg = quackle.LexiconParameters.findDictionaryFile(lexicon + '.dawg')
+ gaddag = quackle.LexiconParameters.findDictionaryFile(lexicon + '.gaddag')
+ dm.lexiconParameters().loadDawg(dawg)
+ dm.lexiconParameters().loadGaddag(gaddag)
+
+ dm.strategyParameters().initialize(lexicon)
+ return dm
+
+
+def getComputerPlayer(dm, name='Speedy Player'):
+ player, found = dm.computerPlayers().playerForName(name)
+ assert found
+ player = player.computerPlayer()
+ return player
+
+
+dm = startUp()
+
+# Create a computer player
+player1 = getComputerPlayer(dm)
+print player1.name()
+
+# Create the Game file (.gcg) reader
+gamereader = quackle.GCGIO()
+gamePath = quackle.Util.stdStringToQString('../../test/positions/short_game_with_bad_moves.gcg')
+game = gamereader.read(gamePath, quackle.Logania.MaintainBoardPreparation)
+
+# Get the current position
+position = game.currentPosition()
+
+player1.setPosition(position)
+
+racks = quackle.ProbableRackList()
+unseenbag = position.unseenBag()
+if unseenbag.size() <= dm.parameters().rackSize() + 3:
+ enum = quackle.Enumerator(unseenbag)
+ enum.enumerate(racks)
+ for rack in racks:
+ print rack
+
+movesToShow = 10
+
+print "Board state: \n%s" % position.board().toString()
+print "Move made: %s" % position.moveMade().toString()
+print "Current player: %s" % position.currentPlayer().storeInformationToString()
+print "Turn number: %i" % position.turnNumber()
+
+movelist = player1.moves(10)
+
+# Show 10 moves suggested by computer player
+for move in movelist: print move.toString()
diff --git a/bindings/python/test2_selfplay.py b/bindings/python/test2_selfplay.py
new file mode 100644
index 0000000..bb6e889
--- /dev/null
+++ b/bindings/python/test2_selfplay.py
@@ -0,0 +1,84 @@
+# coding: utf-8
+
+import time
+
+import quackle
+
+def startUp(lexicon='twl06',
+ alphabet='english',
+ datadir='../../data'):
+
+ # Set up the data manager
+ dm = quackle.DataManager()
+ dm.setComputerPlayers(quackle.ComputerPlayerCollection.fullCollection())
+ dm.setBackupLexicon(lexicon)
+ dm.setAppDataDirectory(datadir)
+
+ # Set up the alphabet
+ abc = quackle.AlphabetParameters.findAlphabetFile(alphabet)
+ abc2 = quackle.Util.stdStringToQString(abc) #convert to qstring
+ fa = quackle.FlexibleAlphabetParameters()
+
+ assert fa.load(abc2)
+ dm.setAlphabetParameters(fa)
+
+ # Set up the board
+ board = quackle.BoardParameters()
+ dm.setBoardParameters(board)
+
+ # Find the lexicon
+ dawg = quackle.LexiconParameters.findDictionaryFile(lexicon + '.dawg')
+ gaddag = quackle.LexiconParameters.findDictionaryFile(lexicon + '.gaddag')
+ dm.lexiconParameters().loadDawg(dawg)
+ dm.lexiconParameters().loadGaddag(gaddag)
+
+ dm.strategyParameters().initialize(lexicon)
+ return dm
+
+
+def getComputerPlayer(dm, name='Speedy Player'):
+ player, found = dm.computerPlayers().playerForName(name)
+ assert found
+ player = player.computerPlayer()
+ return player
+
+
+dm = startUp()
+
+p1 = getComputerPlayer(dm)
+p2 = getComputerPlayer(dm)
+
+# Create computer players
+player1 = quackle.Player('Compy1', quackle.Player.ComputerPlayerType, 0)
+player1.setComputerPlayer(p1)
+print player1.name()
+
+player2 = quackle.Player('Compy2', quackle.Player.ComputerPlayerType, 1)
+player2.setComputerPlayer(p2)
+print player2.name()
+
+dm.seedRandomNumbers(42)
+
+game = quackle.Game()
+players = quackle.PlayerList()
+
+players.append(player1)
+players.append(player2)
+
+game.setPlayers(players)
+game.associateKnownComputerPlayers()
+game.addPosition()
+
+for i in range(50):
+ if game.currentPosition().gameOver():
+ print "GAME OVER"
+ break
+
+ player = game.currentPosition().currentPlayer()
+ move = game.haveComputerPlay()
+ #print "Player: " + player.name()
+ print "Rack : " + player.rack().toString()
+ print 'Move: ' + move.toString()
+ print 'Board: \n' + game.currentPosition().board().toString()
+
+ time.sleep(1)
diff --git a/bindings/quackle.i b/bindings/quackle.i
new file mode 100644
index 0000000..e45eb88
--- /dev/null
+++ b/bindings/quackle.i
@@ -0,0 +1,111 @@
+%module quackle
+%{
+#include "fixedstring.h"
+#include "uv.h"
+#include "alphabetparameters.h"
+#include "move.h"
+#include "rack.h"
+#include "bag.h"
+#include "board.h"
+#include "boardparameters.h"
+#include "evaluator.h"
+#include "catchall.h"
+#include "player.h"
+#include "game.h"
+#include "gameparameters.h"
+#include "sim.h"
+#include "computerplayer.h"
+#include "computerplayercollection.h"
+#include "datamanager.h"
+#include "endgame.h"
+#include "endgameplayer.h"
+#include "enumerator.h"
+#include "bogowinplayer.h"
+#include "clock.h"
+#include "generator.h"
+#include "gaddag.h"
+#include "lexiconparameters.h"
+#include "preendgame.h"
+#include "reporter.h"
+#include "resolvent.h"
+#include "strategyparameters.h"
+
+#include <QString>
+#include "quackleio/flexiblealphabet.h"
+#include "quackleio/util.h"
+#include "quackleio/logania.h"
+#include "quackleio/gcgio.h"
+%}
+
+
+%include "std_string.i"
+%include "std_vector.i"
+%include "typemaps.i"
+
+%include "fixedstring.h"
+%include "uv.h"
+%include "alphabetparameters.h"
+
+/*Needed to generate proper iterable types */
+%template(MoveVector) std::vector<Quackle::Move>;
+%template(PlayerVector) std::vector<Quackle::Player>;
+%template(ProbableRackList) std::vector<Quackle::ProbableRack>;
+%template(PositionList) std::vector<Quackle::GamePosition>;
+%template(LetterParameterVector) std::vector<Quackle::LetterParameter>;
+%template(LetterStringVector) std::vector<Quackle::LetterString>;
+
+%include "move.h"
+%include "rack.h"
+%include "bag.h"
+%include "board.h"
+%include "boardparameters.h"
+%include "evaluator.h"
+%include "catchall.h"
+%include "player.h"
+
+using namespace std;
+namespace Quackle
+{
+ class PlayerList : public vector<Player>
+ {
+ public:
+ PlayerList();
+
+ const Player &playerForId(int id, bool &OUTPUT) const;
+ const Player &playerForName(const UVString &name, bool &OUTPUT) const;
+ };
+}
+
+%include "game.h"
+%include "gameparameters.h"
+%include "sim.h"
+%include "computerplayer.h"
+%include "computerplayercollection.h"
+
+%apply SWIGTYPE *DISOWN {Quackle::AlphabetParameters *alphabetParameters};
+%apply SWIGTYPE *DISOWN {Quackle::BoardParameters *boardParameters};
+%apply SWIGTYPE *DISOWN {Quackle::StrategyParameters *lexiconParameters};
+%apply SWIGTYPE *DISOWN {Quackle::LexiconParameters *lexiconParameters};
+%apply SWIGTYPE *DISOWN {Quackle::Evaluator *evaluator};
+%apply SWIGTYPE *DISOWN {Quackle::GameParameters *parameters};
+%apply SWIGTYPE *DISOWN {const Quackle::PlayerList &playerList};
+
+%include "datamanager.h"
+%include "endgame.h"
+%include "endgameplayer.h"
+%include "enumerator.h"
+%include "bogowinplayer.h"
+%include "clock.h"
+%include "generator.h"
+%include "gaddag.h"
+%include "lexiconparameters.h"
+%include "preendgame.h"
+%include "reporter.h"
+%include "resolvent.h"
+%include "strategyparameters.h"
+
+%include <QString>
+%include "quackleio/flexiblealphabet.h"
+%include "quackleio/util.h"
+%include "quackleio/logania.h"
+%include "quackleio/gcgio.h"
diff --git a/quackleio/gcgio.cpp b/quackleio/gcgio.cpp
index 9209be5..8f8112f 100644
--- a/quackleio/gcgio.cpp
+++ b/quackleio/gcgio.cpp
@@ -30,6 +30,24 @@ GCGIO::GCGIO()
{
}
+Quackle::Game *GCGIO::read(const QString &filename, int flags)
+{
+ QFile file(filename);
+ Quackle::Game *ret = new Quackle::Game;
+
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ UVcerr << "Could not open gcg " << QuackleIO::Util::qstringToString(filename) << endl;
+ return ret;
+ }
+
+ QTextStream in(&file);
+ ret = read(in, flags);
+ file.close();
+
+ return ret;
+}
+
Quackle::Game *GCGIO::read(QTextStream &stream, int flags)
{
Quackle::Game *ret = new Quackle::Game;
diff --git a/quackleio/gcgio.h b/quackleio/gcgio.h
index 477f84f..a219c9f 100644
--- a/quackleio/gcgio.h
+++ b/quackleio/gcgio.h
@@ -30,6 +30,7 @@ public:
GCGIO();
~GCGIO() {};
+ virtual Quackle::Game *read(const QString &filename, int flags);
virtual Quackle::Game *read(QTextStream &stream, int flags);
virtual bool canRead(QTextStream &stream) const;
virtual void write(const Quackle::Game &game, QTextStream &stream);