stack_wars 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ Stack Wars is an abstract board game currently being developed by Gregory Brown
2
+ (@seacreature) and Jia Wu (@sindhri)
3
+
4
+ The game itself can be played on Chess or Go board as long as you have some
5
+ stackable objects available to you (coins or bingo markers work fine). However,
6
+ the goal of this project is to build a computerized version so that anyone can
7
+ play without any special equipment.
8
+
9
+ See the RULES.txt file for an explanation of how the game works, and
10
+ follow the instructions below.
11
+
12
+ ## To try out the game
13
+
14
+ First install the `stack_wars` Ruby gem
15
+
16
+ $ gem install stack_wars
17
+
18
+ Next, step through a sample game to get a sense of how things work
19
+
20
+ $ stack_wars demo
21
+
22
+ If the demo made sense, start up your own game. Make sure to have a friend
23
+ to share the keyboard with, as there are no bots yet. Rudimentary online
24
+ games can be done via tmux or screen, but only if you already know
25
+ how to use those tools and have a shared server handy ;)
26
+
27
+ $ stack_wars
28
+
29
+ If the demo didn't make sense, you can review the rules once more:
30
+ (uses the `less` command line tool)
31
+
32
+ $ stack_wars rules
33
+
34
+ If things still don't make sense, you may want to wait until this project is
35
+ farther along before playing with it further. But I'm happy to answer whatever
36
+ questions you might have: gregory.t.brown@gmail.com
37
+
38
+ _Please note that right now this game has a very rudimentary command line
39
+ interface and has not been tested on any platforms other than Ruby 1.9.2 /
40
+ Mac OS X 10.6. If you are trying this game out now, please make sure you
41
+ feel comfortable diving into the source code if things don't work as
42
+ expected._
43
+
44
+ ## To contribute to this project
45
+
46
+ There is a lot to be done on this project, and I'd be happy to accept contributions.
47
+ If you'd like to help out, here's where to start:
48
+
49
+ 0) Make sure you've got a working install of Ruby 1.9.2 handy
50
+ 1) Fork the project on github: https://github.com/sandal/stack_wars
51
+ 2) Install Bundler if necessary (gem install bundler) [*]
52
+ 3) Run bundle install [*]
53
+ 4) Run ruby tests/suite.rb and verify tests are passing
54
+ 5) Run ruby examples/sample_game.rb and make sure it works as expected
55
+
56
+ [*] Feel free to skip bundler instructions if you know what you're doing and
57
+ would rather not use Bundler, there are no runtime dependencies on it.
58
+
59
+ Once you have gone through those steps, please email me at
60
+ gregory.t.brown@gmail.com letting me know that you'd like to contribute to the
61
+ project. If you had any trouble with the setup process, you can let me know at
62
+ that time.
63
+
64
+ I will eventually post a roadmap publicly, but it's a bit early for that now. If
65
+ you get in touch with me, I'll work with you to figure out what you can work on
66
+ based on your interests and the needs of the project.
67
+
68
+ _NOTE: Contributors retain copyright to their work but must agree to release their
69
+ contributions under the [GNU Affero GPL version
70
+ 3](http://www.gnu.org/licenses/agpl.html)_
@@ -0,0 +1,113 @@
1
+ Stack Wars is an abstract board game played on a two dimensional grid, similar
2
+ to a Chess or Go board. The game is currently still being play tested /
3
+ balanced, but the rules below should give you enough to try it out on your own.
4
+
5
+ == Board layout + setup
6
+
7
+ The board represents a battlefield that two players must
8
+ fight for control over, with the goal of invading each other's bases. The ASCII
9
+ representation below shows a standard 9x9 grid representing the battlefield.
10
+
11
+ 0 1 2 3 4 5 6 7 8
12
+ WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
13
+ 0 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
14
+ | | | | | | | | |
15
+ 1 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
16
+ | | | | | | | | |
17
+ 2 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
18
+ | | | | | | | | |
19
+ 3 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
20
+ | | | | | | | | |
21
+ 4 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
22
+ | | | | | | | | |
23
+ 5 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
24
+ | | | | | | | | |
25
+ 6 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
26
+ | | | | | | | | |
27
+ 7 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
28
+ | | | | | | | | |
29
+ 8 (___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)--(___)
30
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
31
+
32
+ The battlefield starts off empty (as shown above), with each player holding a
33
+ number of armies in reserve equal to three times the width of the battlefield.
34
+ For example, on a 9x9 grid, each player starts off with 27 armies, on a 13x13
35
+ each player starts off with 39 armies, and so on.
36
+
37
+ == Possible turn actions
38
+
39
+ Black starts the game, and then play alternates as each player takes one of the
40
+ following actions per turn.
41
+
42
+ - FORTIFY a CONTROLLED territory by adding a single army from reserves
43
+ - MOVE a single army from a CONTROLLED territory to an adjacent
44
+ UNCLAIMED territory
45
+ - ATTACK a single enemy territory adjacent to one of the player's
46
+ CONTROLLED territories
47
+ - INVADE the enemy base (may be a MOVE or ATTACK, details explained later)
48
+
49
+ Throughout the game, the following territories are considered to be CONTROLLED
50
+ by the active player:
51
+
52
+ 1) Anything that lies on the BASELINE (i.e. boundary line between the
53
+ battlefield and the player's base). This works out to any territory
54
+ in row 0 for white, and any territory in row N for black, where N is
55
+ the last row of the board.
56
+
57
+ 2) Any territory which has at least one of the active player's army fortified
58
+ within it.
59
+
60
+ Some restrictions apply to how turns play out, depending on game conditions:
61
+
62
+ * In order to FORTIFY a position, the active player must have at least one
63
+ army in reserves.
64
+
65
+ * Adjacent territories are a single edge away horizontally or vertically,
66
+ but not diagonally. E.g. adjacent territories to (2,2) are:
67
+ (2,1), (2,3), (1,2), (3,2). You cannot MOVE, ATTACK, or INVADE diagonally
68
+ at any point in time.
69
+
70
+ * Two or more armies within a single territory form a STACK. If moving from
71
+ a STACK to another position, only a single army is moved, not the
72
+ entire STACK.
73
+
74
+ * You can only carry out an ATTACK from a territory which does not contain
75
+ a STACK (i.e. a position with a single army)
76
+
77
+ * If an ATTACK on an enemy territory causes that territory to becomes
78
+ unoccupied, you must immediately move the army you attacked with
79
+ into that territory.
80
+
81
+ * Whenever an army is removed from the battlefield via an ATTACK,
82
+ it is immediately removed from play, and does not count for or against
83
+ either player's score, nor does it get returned to the either player's
84
+ reserves.
85
+
86
+ == Gaining Points
87
+
88
+ An INVASION is carried out by moving one of the active player's armies into an
89
+ adjacent territory which is part of the enemy's BASELINE. This can be done via a
90
+ MOVE or an ATTACK. As soon as the active player's army is moved onto the
91
+ baseline, it is removed from play, and the active player gets one point added to
92
+ their score.
93
+
94
+ == Ending the game
95
+
96
+ At the exact moment that one player has no armies in play as well as no armies
97
+ in reserve, the game immediately ends. If one player has more points than the
98
+ other, the player with the greater amount of points. If instead each player
99
+ has an equal number of points, the game ends in a draw.
100
+
101
+ Alteratively, both players have the option of resigning at any time. Because
102
+ this is a game in which it may be obvious who the winner is well ahead of the
103
+ standard end game conditions, it should not be considered impolite to resign
104
+ when the battle is no longer interesting.
105
+
106
+ == Questions / Suggestions?
107
+
108
+ Email gregory.t.brown@gmail.com
109
+
110
+ == Implementation
111
+
112
+ You can find the source code for this game at:
113
+ http://github.com/sandal/stack_wars
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # NOTE: This script is just a proof of concept.
4
+ # This game will eventually have a GUI of some sort
5
+
6
+ require_relative "../lib/stack_wars"
7
+
8
+ def play_game
9
+ field = StackWars::Battlefield.new
10
+ game = StackWars::Game.new(field)
11
+
12
+ client = StackWars::TextClient.new(game)
13
+
14
+ message = catch(:game_over) do
15
+ loop do
16
+ system "clear"
17
+ puts field
18
+
19
+ puts
20
+ puts "Current Score: #{game.active_player.color}: "+
21
+ "#{game.active_player.successful_invasions}, "+
22
+ "#{game.opponent.color}: "+
23
+ "#{game.opponent.successful_invasions}"
24
+
25
+ print "#{game.active_player.color}:#{game.active_player.reserves} > "
26
+
27
+ begin
28
+ move = yield
29
+
30
+ if move[/resign/i]
31
+ throw :game_over, "#{game.active_player.color} resigned"
32
+ else
33
+ client.play(move)
34
+ end
35
+ rescue StackWars::Errors::ParseError
36
+ puts "invalid command, press enter to continue"
37
+ gets
38
+ rescue StackWars::Errors::IllegalMove
39
+ puts "that move is illegal, press enter to continue"
40
+ gets
41
+ end
42
+ end
43
+ end
44
+
45
+ puts field
46
+ puts message
47
+ end
48
+
49
+ case ARGV[0]
50
+ when "rules"
51
+ system("less #{File.dirname(__FILE__)}/../RULES.txt")
52
+ when "demo"
53
+ file = "#{File.dirname(__FILE__)}/../example/sample-moves.txt"
54
+ moves = File.foreach(file)
55
+ play_game do
56
+ move = moves.next
57
+ puts "#{move}\nhit enter to continue"
58
+ $stdin.gets
59
+ move
60
+ end
61
+ else
62
+ play_game { $stdin.gets }
63
+ end
@@ -0,0 +1,190 @@
1
+ 3 8
2
+ 6 0
3
+ 6 8
4
+ 6 0 6 1
5
+ 6 8 6 7
6
+ 6 1 6 2
7
+ 6 7 6 6
8
+ 6 2 6 3
9
+ 6 6 6 5
10
+ 6 3
11
+ 6 5
12
+ 6 3 6 4
13
+ 6 5 5 5
14
+ 6 4 7 4
15
+ 6 5 6 6
16
+ 7 4 7 5
17
+ 5 5
18
+ 7 5
19
+ 5 5 5 6
20
+ 7 5 7 6
21
+ 7 8
22
+ 6 3 7 3
23
+ 8 8
24
+ 7 3 7 4
25
+ 8 8
26
+ 7 4 8 4
27
+ 8 8 8 7
28
+ 8 4 8 5
29
+ 5 5 5 4
30
+ 8 5
31
+ 7 8 7 7
32
+ 8 5 8 6
33
+ 7 7 7 6
34
+ 8 6 7 6
35
+ 5 4 5 3
36
+ 8 5
37
+ 5 3 5 2
38
+ 8 5 8 6
39
+ 5 2
40
+ 7 6 6 6
41
+ 5 2 5 1
42
+ 6 6 5 6
43
+ 4 8
44
+ 7 5
45
+ 5 8
46
+ 7 5 7 6
47
+ 5 2
48
+ 7 6
49
+ 8 7 7 7
50
+ 7 6 6 6
51
+ 7 8
52
+ 6 6
53
+ 6 8
54
+ 5 6
55
+ 5 8 5 7
56
+ 5 6 4 6
57
+ 5 8
58
+ 4 6
59
+ 5 1 5 0
60
+ 4 6 3 6
61
+ 5 2 5 1
62
+ 3 6
63
+ 5 2
64
+ 3 6 3 7
65
+ 5 1 5 0
66
+ 3 7 3 8
67
+ 3 8
68
+ 3 6
69
+ 5 8 5 7
70
+ 3 6 3 7
71
+ 5 7 5 8
72
+ 3 7 3 8
73
+ 3 8
74
+ 5 0
75
+ 6 8 6 7
76
+ 7 6 7 7
77
+ 7 8 7 7
78
+ 5 6 5 7
79
+ 5 8 5 7
80
+ 6 6 5 6
81
+ 5 7 5 6
82
+ 6 6 5 6
83
+ 5 2 4 2
84
+ 4 6
85
+ 4 8 4 7
86
+ 4 6 3 6
87
+ 4 7 4 6
88
+ 5 6 4 6
89
+ 3 8 3 7
90
+ 3 6 2 6
91
+ 4 2 4 1
92
+ 3 6 3 7
93
+ 3 8
94
+ 2 6 2 7
95
+ 3 8 3 7
96
+ 2 7 3 7
97
+ 4 8
98
+ 4 6
99
+ 6 7 5 7
100
+ 4 6 5 6
101
+ 5 8
102
+ 3 7
103
+ 3 8
104
+ 3 7 3 6
105
+ 5 2
106
+ 8 6
107
+ 5 2 4 2
108
+ 8 6 7 6
109
+ 7 8
110
+ 3 6
111
+ 3 8 3 7
112
+ 3 6 2 6
113
+ 3 7 3 6
114
+ 2 6 3 6
115
+ 3 8
116
+ 7 5
117
+ 4 2
118
+ 7 5 6 5
119
+ 4 1 4 0
120
+ 4 0
121
+ 4 2 4 1
122
+ 4 0 4 1
123
+ 4 2 4 1
124
+ 6 5 6 6
125
+ 6 8
126
+ 6 6
127
+ 6 8 6 7
128
+ 6 6 6 5
129
+ 5 2 5 1
130
+ 5 0 5 1
131
+ 4 1 5 1
132
+ 3 6
133
+ 4 8 4 7
134
+ 4 6 4 7
135
+ 5 7 4 7
136
+ 3 6 2 6
137
+ 2 8
138
+ 2 6
139
+ 2 8 2 7
140
+ 2 6 1 6
141
+ 2 7 2 6
142
+ 1 6 2 6
143
+ 3 8 3 7
144
+ 3 6 2 6
145
+ 3 7 2 7
146
+ 2 6 1 6
147
+ 2 7 2 6
148
+ 1 6 2 6
149
+ 4 7 3 7
150
+ 2 6
151
+ 3 7 2 7
152
+ 2 6 1 6
153
+ 2 7 2 6
154
+ 1 6 2 6
155
+ 5 8 5 7
156
+ 2 6 2 7
157
+ 5 7 4 7
158
+ 2 7
159
+ 4 7 3 7
160
+ 2 7 1 7
161
+ 3 7 2 7
162
+ 1 7 2 7
163
+ 7 8 6 8
164
+ 2 7
165
+ 6 8 5 8
166
+ 2 7
167
+ 5 8 4 8
168
+ 2 7 2 8
169
+ 4 8 3 8
170
+ 2 7 2 8
171
+ 5 1 5 0
172
+ 7 6 7 7
173
+ 6 7 7 7
174
+ 2 7 2 8
175
+ 3 8 3 7
176
+ 5 6 5 7
177
+ 3 7 3 6
178
+ 5 7 5 8
179
+ 3 6 4 6
180
+ 7 5 7 6
181
+ 7 7 7 8
182
+ 6 6 6 7
183
+ 4 6 5 6
184
+ 6 5 6 6
185
+ 5 6 6 6
186
+ 7 6 6 6
187
+ 7 8 7 7
188
+ 6 7 7 7
189
+ 8 8 8 7
190
+ 8 6 8 7
@@ -0,0 +1,31 @@
1
+ require_relative "../lib/stack_wars"
2
+
3
+ field = StackWars::Battlefield.new
4
+ game = StackWars::Game.new(field)
5
+ moves = File.foreach("#{File.dirname(__FILE__)}/sample-moves.txt")
6
+
7
+ client = StackWars::TextClient.new(game)
8
+
9
+ message = catch(:game_over) do
10
+ loop do
11
+ system "clear"
12
+ puts field
13
+
14
+ puts
15
+ puts "Current Score: #{game.active_player.color}: "+
16
+ "#{game.active_player.successful_invasions}, "+
17
+ "#{game.opponent.color}: "+
18
+ "#{game.opponent.successful_invasions}"
19
+
20
+ command = moves.next
21
+ print "#{game.active_player.color}:#{game.active_player.reserves} > #{command}"
22
+ client.play(command)
23
+
24
+
25
+ puts "hit enter to continue"
26
+ gets
27
+ end
28
+ end
29
+
30
+ puts field
31
+ puts message