public
Description: Multi-player, turn-based games library.
Homepage: http://vying.org
Clone URL: git://github.com/eki/vying.git
vying / README
100644 190 lines (124 sloc) 6.203 kb
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
= Vying
 
Vying is a library for multi-player, turn-based, strategy games. The goal is to
make it easy to implement a large number of games very quickly, with only a
small amount of code. This includes the rules (or game logic) and AI, but does
not extend to user interface code (though there is a small, primitive
command-line program for playing games). This library is the core of Vying
Games <http://vying.org>.
 
Some of vying's features are:
 
* Support for a wide range of game elements
  * Games with random starting positions
  * Games with random events (dice rolls, for example)
  * While turn-based, games may feature simultaneous turns (or sealed moves)
* Includes support for board games and card games (though the card game
  support is a little primitive still)
* Most "rules" can be implemented approximately 100 lines of Ruby code
* Fairly simple bot interface can make AI programming fairly simple (this
  needs improvement)
 
 
== Development Info
 
This README is just a brief introduction to this library. For more detailed /
up-to-date info see the dev wiki: <http://vying.org/wiki/dev>.
 
 
== The Games
 
See <http://vying.org/wiki/games> for a list of games that have
already been implemented. Planned games are also listed there.
 
 
== Installation
 
Vying is available as a gem:
 
  gem install vying --source http://vying.org
 
This gem has a native C extension to provide better performance (in some
areas). There are Ruby equivalents for all the C code, meaning the extension
is not necessary. It's loaded dynamically if present. However, installation
of the 'vying' gem will fail on platforms that can't build the C (despite the
fact that the gem would still be 100% functional). So, the 'vying-pure' gem is
provided. This is essentially the same gem, with all the C removed.
 
  gem install vying-pure --source http://vying.org
 
Because the 'vying-pure' gem has no dependencies and consists solely of pure
Ruby, it should be portable to any platform that Ruby supports.
 
Or, if you prefer, the code is available at Github:
 
  git clone git://github.com/eki/vying.git
 
 
== Command-Line Interface
 
This package includes a small command-line application called 'vying' that can
be invoked in the following ways. To get more help on any of these commands
type:
 
  vying --help
 
=== To play a game:
 
  vying play --rules Breakthrough --player white=Human --player black=RandomBot
 
=== To benchmark a game:
 
  vying bench --rules Breakthrough
 
=== To check the branching factor of a game:
 
  vying branch --rules Breakthrough
 
=== To get info about a game:
 
  vying info --rules Breakthrough
 
== Example Code
 
At the heart of the library are the Rules for a game. For example:
 
  Rules.create( "TicTacToe" ) do
    name "Tic Tac Toe"
    version "1.0.0"
  end
 
 
The above is a start at defining the Rules for Tic Tac Toe. The Rules contain
largely static information about the game, such as the name of the game or
the player names. Below, we start to define what a Position in a game of
Tic Tac Toe would look like. A Game will be made up (in part) of a series
of Position, each position is created by changing the previous position by
playing a move.
 
  Rules.create( "TicTacToe" ) do
    name "Tic Tac Toe"
    version "1.0.0"
 
    players :x, :o
 
    position do
      attr_reader :board
 
      def init
        @board = Board.new( 3, 3 )
      end
    end
  end
 
 
In the above example the players (:x, :o) were defined. The player symbols
declared in the order that the players take turns. In this case, :x will go
first, and the :o.
 
In addition, the position is defined to include a 3x3 board. It can be
accessed through a method 'board', like so:
 
  position = TicTacToe.new
  puts position.board
 
If we were to continue this example, we'd need to define a #moves method to
return tokens (Strings) representing each move. In Tic Tac Toe, we'd probably
return the coordinates representing where the player would place an X or O on
the board. We'd also define an #apply! method which would take a move token
and alter the position state.
 
Finally (no pun intended), we'd define a #final? method that would return true
if the position is final (the game is over). We'd also define #winner?,
#loser?, and #draw? methods.
 
There are more methods that can be defined depending on the game being
implemented but those are the basics at the core of every game.
 
Once some rules have been defined, we can play around with them like so:
 
  g = Game.new TicTacToe
 
A Game represents an entire tree of positions.
 
  g.moves # Returns an array of possible moves
  g << g.moves.first # Make the first move
 
  g.turn # Who's turn is it?
 
  g.board # Game passes calls through to the underlying
                           # (last) position, this is the equivalent of
 
  g.history.last.board
  g.history[3].board # History can be used like an array to look back
                           # at any position
 
  g.move?( "a1" ) # Is "a1" a valid move?
  g.move?( "a1", :x ) # Is "a1" a valid move for :x?
 
  g.has_moves # Returns a list of all the players who can move.
                           # Some games allow simultaneous moves, so checking
                           # #has_moves is safer than using #turn
 
  g.final? # Is the game over?
  g.winner?( :x ) # Did :x win the game?
  g.draw? # Is the game a draw?
  
  if g.has_score?
    g.score( :x ) # If the game has a score, what was :x's score?
  end
 
  # Setup a random game..
 
  g = Game.new TicTacToe
  g[:x] = RandomBot.new
  g[:o] = RandomBot.new
 
  g.step # Play a single move (Game asks the appropriate Bot for it's move)
  g.play # Play out the entire game.
 
 
== The Future
 
It's the goal of this library to document games through implementation.
Towards that end adding games, and making it easier to add games is this
library's top priority. Secondarily, providing AI utility code, and bots that
play the games is also important. Lastly, it's the goal of this library to
provide some kind of client connectivity to the Vying Games server.