eschaton 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/README.md +25 -0
- data/bin/eschaton +70 -0
- data/lib/eschaton/combatant.rb +177 -0
- data/lib/eschaton/game.rb +198 -0
- data/lib/eschaton/gamemaster.rb +52 -0
- data/lib/eschaton/strategic_targets.rb +48 -0
- data/spec/eschaton/combatant_spec.rb +37 -0
- data/spec/eschaton/game_spec.rb +61 -0
- data/spec/eschaton/strategic_targets_spec.rb +18 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 36c88e36d0464df530240a63f138783a11ab9c05
|
4
|
+
data.tar.gz: 953284e6342cbbd4b7161ef149d0655ab398e4ed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c22e4cbb81aba1e6a6fba513729a8e36bc974ac3b4f8b04a7bfaa917c39ff449c9a8f1cb467041428b5f99a1f9f390bca65f5e508f1bfad92168dc54f957539
|
7
|
+
data.tar.gz: 242280e8543ac809f4e3a21d9c0ec6dd7155a037d92ada4e0ffb2f5c68b2b1a792c15f3aa0d5cb0e38a885b5ac12c8f5c4ae7532dadb2964b26170f06914139f
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT LICENSE
|
2
|
+
|
3
|
+
Copyright (c) 2014, Sean Parr
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Eschaton for Ruby
|
2
|
+
|
3
|
+
|
4
|
+
An attempt to adapt the game of Eschaton, from David Foster Wallace's [*Infinite Jest*](http://en.wikipedia.org/wiki/Infinite_Jest), into a text-based Ruby game. Definitely a work in progress. Not much to look at now, but I'll update the README when the game gets a little more involved.
|
5
|
+
|
6
|
+
|
7
|
+
To install:
|
8
|
+
|
9
|
+
gem install eschaton
|
10
|
+
|
11
|
+
To play:
|
12
|
+
|
13
|
+
eschaton
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
License
|
19
|
+
----
|
20
|
+
|
21
|
+
MIT
|
22
|
+
|
23
|
+
Copyright (c) 2014, Sean Parr
|
24
|
+
|
25
|
+
Eschaton is provided as-is under the MIT license. For more information see LICENSE.
|
data/bin/eschaton
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/eschaton/game'
|
4
|
+
|
5
|
+
new_game = Eschaton::Game.new
|
6
|
+
|
7
|
+
puts "\n \n \n"
|
8
|
+
|
9
|
+
puts "ESCHATON".center(100, '-')
|
10
|
+
|
11
|
+
puts "\n \n \n "
|
12
|
+
|
13
|
+
puts "c:\\Pink2\\Mathpak\\Endstat...\n "
|
14
|
+
|
15
|
+
3.times do
|
16
|
+
sleep(1)
|
17
|
+
puts "\n...loading...\n"
|
18
|
+
sleep(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
puts "\nEschaton is a thermonuclear warfare game played by the students at the Enfield Tennis Academy in Boston."
|
22
|
+
puts "You will belong to a Combatant nation, between AMNAT, SOVWAR, REDCHI, INDPAK, IRLIBSYR, or SOUTHAF."
|
23
|
+
puts "The point of the game is to lob a tennis ball (thermonuclear warhead) accurately at an opposing combatant's"
|
24
|
+
puts "strategic target, of which there are many, and with their own corresponding point values."
|
25
|
+
puts "Certain strategic targets carry higher point values but due to their scarcity, are harder to hit."
|
26
|
+
puts "A given Eschaton's winning team is simply that Combatant with the most favorable ratio of points for INDDIR -"
|
27
|
+
puts "Infliction of Death, Destruction, and Incapacity of Response - to SUFDDIR - self-evident.\n "
|
28
|
+
|
29
|
+
puts "Got it? (press Enter)\n "
|
30
|
+
|
31
|
+
gets
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
loop do
|
36
|
+
|
37
|
+
puts "\nHow many rounds of Eschaton would we be playing? ('quit' or 'q' to exit)\n "
|
38
|
+
|
39
|
+
answer = gets.chomp
|
40
|
+
|
41
|
+
case answer
|
42
|
+
|
43
|
+
when /^\d+$/
|
44
|
+
|
45
|
+
new_game.control_combatant
|
46
|
+
|
47
|
+
gets
|
48
|
+
|
49
|
+
new_game.play(answer.to_i)
|
50
|
+
|
51
|
+
when 'quit', 'q'
|
52
|
+
puts "\n \n "
|
53
|
+
puts "Thanks for playing ESCHATON".center(80, ' ')
|
54
|
+
puts "\n \n "
|
55
|
+
puts "\"See yourself in your opponents. They will bring you to understand the game.".center(80, ' ')
|
56
|
+
puts "To accept the fact that the Game is about managed fear.".center(80, ' ')
|
57
|
+
puts "That its object is to send from yourself what you hope will not return.\"\n ".center(80, ' ')
|
58
|
+
puts ' - David Foster Wallace'.rjust(80, ' ')
|
59
|
+
puts "\nP.S. Allston Rules!\n "
|
60
|
+
break
|
61
|
+
|
62
|
+
else
|
63
|
+
|
64
|
+
puts "\nError: Please enter a number"
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require_relative 'strategic_targets'
|
2
|
+
|
3
|
+
module Eschaton
|
4
|
+
|
5
|
+
class Combatant
|
6
|
+
attr_accessor :nation, :megatonnage, :inddir, :sufddir, :accuracy, :defcon, :rad_level, :em_immunity, :population, :score
|
7
|
+
|
8
|
+
# megatonnage =
|
9
|
+
# integrally regressed ratio of:
|
10
|
+
# yearly military budget as percentage of yearly GNP
|
11
|
+
# inverse of stratego-tactical expenditures as percentage of yearly military budget
|
12
|
+
# GNP/Military // Military/Nuke ratio
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(nation, megatonnage: 400, defcon: 5, sufddir: 0.0, inddir: 0.0,
|
16
|
+
sacpop: 0, rad_level: 0, em_immunity: true,
|
17
|
+
population: 300_000_000, accuracy: 0, score: 0)
|
18
|
+
|
19
|
+
@nation = nation.to_s.upcase
|
20
|
+
@sufddir = sufddir #suffering of death, destruction, and incapacitation of response
|
21
|
+
@inddir = inddir #infliction of death, destruction, and incapacitation of response
|
22
|
+
@defcon = defcon
|
23
|
+
@sacpop = sacpop # strikes against civilian populations
|
24
|
+
@megatonnage = megatonnage # distrubtion of megatonnage determined by mean-value theorem of integrals
|
25
|
+
@rad_level = rad_level
|
26
|
+
@em_immunity = em_immunity
|
27
|
+
@population = population
|
28
|
+
@accuracy = accuracy
|
29
|
+
@score = score
|
30
|
+
@targets_hit = Hash.new(0)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
"#{@nation.ljust(20, '.')} SUFDDIR: #{@sufddir} / INDDIR: #{@inddir} / MEGATONNAGE: #{@megatonnage}\nDEFCON: #{@defcon} / RADIATION: #{@rad_level} / EM-PULSE IMMUNITY: #{@em_immunity} / SURVIVING POPULATION: #{@population}\n "
|
35
|
+
end
|
36
|
+
|
37
|
+
def <=>(other)
|
38
|
+
other.score <=> score
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# statistics
|
43
|
+
|
44
|
+
|
45
|
+
def scoretotal
|
46
|
+
if @sufddir > 0
|
47
|
+
@score = @inddir/@sufddir
|
48
|
+
@score.round(2)
|
49
|
+
else
|
50
|
+
@score = @inddir
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def hit_target(target)
|
55
|
+
@targets_hit[target.name.to_sym] += target.ptvalue
|
56
|
+
end
|
57
|
+
|
58
|
+
def target_stats
|
59
|
+
total_target_points = @targets_hit.values.reduce(0) {|sum, val| sum + val }
|
60
|
+
puts "Total INDDIR from ALL targets: ".upcase + total_target_points.to_s
|
61
|
+
sleep(1)
|
62
|
+
end
|
63
|
+
|
64
|
+
def each_hit_target
|
65
|
+
@targets_hit.each do |name, value|
|
66
|
+
yield Target.new(name, value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
# attacks
|
74
|
+
|
75
|
+
|
76
|
+
def lob(opponent)
|
77
|
+
if @megatonnage > 0
|
78
|
+
@inddir += 30
|
79
|
+
@megatonnage -= 5
|
80
|
+
|
81
|
+
opponent.sufddir += 30
|
82
|
+
if opponent.defcon > 1
|
83
|
+
opponent.defcon -= 1
|
84
|
+
end
|
85
|
+
opponent.rad_level += 20
|
86
|
+
opponent.population -= rand(100_000..200_000)
|
87
|
+
|
88
|
+
@score = self.scoretotal
|
89
|
+
puts "#{@nation} lobs a warhead at #{opponent.nation} (+30 INDDIR)!"
|
90
|
+
else
|
91
|
+
puts "#{@nation}'s megaton supply has been depleted."
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def sacpop(opponent)
|
96
|
+
if @megatonnage > 0
|
97
|
+
@inddir += 100
|
98
|
+
@sacpop += 1
|
99
|
+
@megatonnage -= 5
|
100
|
+
|
101
|
+
opponent.sufddir += 100
|
102
|
+
if opponent.defcon > 2
|
103
|
+
opponent.defcon -= 2
|
104
|
+
else
|
105
|
+
opponent.defcon = 1
|
106
|
+
end
|
107
|
+
opponent.rad_level += 20
|
108
|
+
opponent.population -= rand(100_000..200_000)
|
109
|
+
|
110
|
+
@score = self.scoretotal
|
111
|
+
puts "#{@nation} strikes one of #{opponent.nation}'s civilian populations..."
|
112
|
+
puts self
|
113
|
+
puts ' '
|
114
|
+
else
|
115
|
+
puts "#{@nation}'s megaton supply has been depleted.\ "
|
116
|
+
puts self
|
117
|
+
puts ' '
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def mirv(opponent)
|
122
|
+
if @megatonnage > 350
|
123
|
+
puts "Dear God. #{@nation} launches a neatly tied MIRV jockstrap at #{opponent.nation}..."
|
124
|
+
@inddir += 100
|
125
|
+
@megatonnage -= 350
|
126
|
+
|
127
|
+
opponent.sufddir += 300
|
128
|
+
opponent.defcon = 1
|
129
|
+
opponent.rad_level += 100
|
130
|
+
opponent.population -= rand(100_000_000..200_000_000)
|
131
|
+
8.times do
|
132
|
+
GameMaster.spasex(self, opponent)
|
133
|
+
sleep(1)
|
134
|
+
end
|
135
|
+
|
136
|
+
@score = self.scoretotal
|
137
|
+
puts self
|
138
|
+
puts ' '
|
139
|
+
else
|
140
|
+
puts "#{@nation}'s megaton supply is insufficient for this attack.\n "
|
141
|
+
puts self
|
142
|
+
puts ' '
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
# def empulse(opponent)
|
152
|
+
# puts "#{@nation} fires an electro-magnetic pulse at #{opponent.nation}'s comm. systems..."
|
153
|
+
# if opponent.em_immunity == false
|
154
|
+
# opponent.comm_loss
|
155
|
+
# puts "#{opponent.nation}'s comm. systems have been shut down!"
|
156
|
+
# else
|
157
|
+
# puts "#{opponent.nation}'s em-pulse immunity is too high. #{opponent.nation} retains all communications."
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
# # statuses
|
164
|
+
|
165
|
+
# def comm_loss
|
166
|
+
# #loss of next turn
|
167
|
+
# end
|
168
|
+
|
169
|
+
# def incapacitated?
|
170
|
+
# #ratio of SUFDDIR, loss of turns
|
171
|
+
# end
|
172
|
+
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require_relative 'combatant'
|
2
|
+
require_relative 'gamemaster'
|
3
|
+
require_relative 'strategic_targets'
|
4
|
+
|
5
|
+
module Eschaton
|
6
|
+
|
7
|
+
class Game
|
8
|
+
|
9
|
+
# 400 5-megaton warheads total, disbursed
|
10
|
+
|
11
|
+
attr_accessor :combatants, :beanie_status
|
12
|
+
|
13
|
+
def initialize(name: "Eschaton", beanie_status: 'Normal Game Conditions')
|
14
|
+
@beanie_status = beanie_status
|
15
|
+
@combatants = [Combatant.new(:amnat), Combatant.new(:sovwar), Combatant.new(:redchi),
|
16
|
+
Combatant.new(:irlibsyr), Combatant.new(:southaf), Combatant.new(:indpak)]
|
17
|
+
# status can change to 'cessation of hostilities'
|
18
|
+
# and 'utter global crisis'
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
# initializes player control of random Combatant. A bit hacky, yes
|
25
|
+
|
26
|
+
def control_combatant
|
27
|
+
@playercombatant = @combatants.delete_at(rand(@combatants.length))
|
28
|
+
puts "\nFor this game of Eschaton, you've been designated to be represent #{@playercombatant.nation}. (press Enter)\n "
|
29
|
+
@playercombatant.nation.prepend '*'
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
# gameplay
|
43
|
+
|
44
|
+
|
45
|
+
def play(rounds)
|
46
|
+
|
47
|
+
1.upto(rounds) do |r|
|
48
|
+
puts "\nRound #{r}\n "
|
49
|
+
|
50
|
+
puts "Which Combatant will you attack?"
|
51
|
+
puts @combatants.map{|x| x.nation }.sort.join(', ')
|
52
|
+
|
53
|
+
puts ' '
|
54
|
+
|
55
|
+
# This loop cycles through the @combatants array for a match between the user's input
|
56
|
+
# and each Combatant's nation abbreviation. If match found, we store the Combatant in
|
57
|
+
# the @target variable. If no match, we ask user to try again.
|
58
|
+
|
59
|
+
loop do
|
60
|
+
target = gets.chomp.upcase
|
61
|
+
|
62
|
+
puts ' '
|
63
|
+
|
64
|
+
if @combatants.any? { |i| i.nation == target }
|
65
|
+
@target = @combatants.find {|x| x.nation == target }
|
66
|
+
GameMaster.spasex(@playercombatant, @target)
|
67
|
+
sleep(2)
|
68
|
+
break
|
69
|
+
else
|
70
|
+
puts "Please enter the name of a Combatant:"
|
71
|
+
puts @combatants.map{|x| x.nation }.sort.join(', ')
|
72
|
+
puts ' '
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# puts "Enter an nuclear attack sequence:"
|
78
|
+
|
79
|
+
# loop do
|
80
|
+
|
81
|
+
# puts "LOB [Nuclear Attack]"
|
82
|
+
# puts "SACPOP [Strike Against Civilian Population]"
|
83
|
+
# puts "MIRV [Multiple Independent Reetry Vehicle]\n "
|
84
|
+
|
85
|
+
# attack = gets.chomp.upcase
|
86
|
+
|
87
|
+
# puts ' '
|
88
|
+
|
89
|
+
# case attack
|
90
|
+
# when "LOB"
|
91
|
+
# GameMaster.spasex(@playercombatant, @target)
|
92
|
+
# break
|
93
|
+
# when "SACPOP"
|
94
|
+
# @playercombatant.sacpop(@target)
|
95
|
+
# break
|
96
|
+
# when "MIRV"
|
97
|
+
# @playercombatant.mirv(@target)
|
98
|
+
# break
|
99
|
+
# else
|
100
|
+
# puts "Error: Incorrect Attack Sequence"
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
|
104
|
+
# sleep(2)
|
105
|
+
|
106
|
+
@combatants.each do |c|
|
107
|
+
|
108
|
+
# clone the @combatant array without the current Combatant
|
109
|
+
combatantsclone = @combatants.reject { |x| x.nation == c.nation }
|
110
|
+
combatantsclone << @playercombatant # add @playercombatant to array of attackable Combatants
|
111
|
+
|
112
|
+
opp = combatantsclone.sample
|
113
|
+
|
114
|
+
|
115
|
+
GameMaster.spasex(c, opp)
|
116
|
+
|
117
|
+
combatantsclone.reject! { |x| x.nation == @playercombatant.nation} #removes @playercombatant again
|
118
|
+
sleep(2)
|
119
|
+
end
|
120
|
+
|
121
|
+
# if @combatants.all? {|c| c.defcon == 1 }
|
122
|
+
# @beanie_status = 'Utter Global Crisis'
|
123
|
+
# puts "\nEvery Combatant has entered DEFCON 1. Otis P. Lord has donned the Red Beanie. #{@beanie_status.upcase}.\n "
|
124
|
+
# sleep(2)
|
125
|
+
# end
|
126
|
+
|
127
|
+
if @combatants.all? {|c| c.megatonnage == 0}
|
128
|
+
@beanie_status = 'Cessation of Hostilities'
|
129
|
+
puts "\nIt appears the Global supply of Nuclear Weapons has been depleted. Otis P. Lord has donned the White Beanie. #{@beanie_status}.\n "
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
puts "END OF GAME".center(30, ".")
|
134
|
+
puts "\npress Enter to calculate results\n "
|
135
|
+
gets
|
136
|
+
puts "\nEndStat calculating results...\n "
|
137
|
+
sleep(2)
|
138
|
+
3.times do
|
139
|
+
puts "calculating...\n "
|
140
|
+
sleep(1)
|
141
|
+
end
|
142
|
+
puts " "
|
143
|
+
finalstats
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
# statistics
|
158
|
+
|
159
|
+
def print_score(combatant)
|
160
|
+
puts "#{combatant.nation} SCORE".ljust(50, '.') + "#{combatant.score} pts. \n "
|
161
|
+
end
|
162
|
+
|
163
|
+
def finalstats
|
164
|
+
@combatants << @playercombatant
|
165
|
+
accuracy_rankings = @combatants.sort {|a,b| b.accuracy <=> a.accuracy }
|
166
|
+
mvl = accuracy_rankings.first
|
167
|
+
if mvl.accuracy = 1
|
168
|
+
puts "Most Valuable Lobber: #{mvl.nation} with #{mvl.accuracy} direct hit!\n "
|
169
|
+
else
|
170
|
+
puts "Most Valuable Lobber: #{mvl.nation} with #{mvl.accuracy} direct hits!\n "
|
171
|
+
end
|
172
|
+
sleep(1.5)
|
173
|
+
|
174
|
+
@combatants.each {|c| c.scoretotal } # calculates the INDDIR/SUFDDIR ratio for a final score.
|
175
|
+
|
176
|
+
score_rankings = @combatants.sort {|a,b| b.score <=> a.score}
|
177
|
+
puts "Final Rankings:\n"
|
178
|
+
puts " "
|
179
|
+
ranknum = 1
|
180
|
+
score_rankings.each do |c|
|
181
|
+
puts "#{ranknum} #{c.nation}:"
|
182
|
+
puts "Total Infliction of Death, Destruction and Incapacitation of Response(INDDIR): #{c.inddir}"
|
183
|
+
puts "Total Suffering of Death, Destruction and Incapacitation of Response(SUFDDIR): #{c.sufddir}"
|
184
|
+
puts "Direct Hits: #{c.accuracy}"
|
185
|
+
c.each_hit_target do |t|
|
186
|
+
puts "Total INDDIR from striking #{t.name}s: #{t.ptvalue}"
|
187
|
+
end
|
188
|
+
c.target_stats
|
189
|
+
print_score(c)
|
190
|
+
ranknum += 1
|
191
|
+
end
|
192
|
+
puts score_rankings.first.nation + ' wins! (press Enter to continue)'
|
193
|
+
gets
|
194
|
+
@playercombatant.nation[0] = ''
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Eschaton
|
2
|
+
|
3
|
+
module GameMaster
|
4
|
+
|
5
|
+
def self.accuracy
|
6
|
+
rand(1..20)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.spasex(combatant, opponent)
|
10
|
+
lobaccuracy = accuracy
|
11
|
+
|
12
|
+
target = StrategicTargets.random
|
13
|
+
|
14
|
+
case accuracy
|
15
|
+
when 18..20
|
16
|
+
combatant.lob(opponent)
|
17
|
+
combatant.accuracy += 1
|
18
|
+
combatant.inddir += 20
|
19
|
+
puts "#{combatant.nation}'s warhead directly (+20 INDDIR) hits a #{target.name}(+#{target.ptvalue} INDDIR)! Ho-ly CROW!"
|
20
|
+
combatant.hit_target(target)
|
21
|
+
combatant.inddir += target.ptvalue
|
22
|
+
puts combatant
|
23
|
+
when 4..17
|
24
|
+
combatant.lob(opponent)
|
25
|
+
puts "#{combatant.nation}'s warhead hit a #{target.name}(+#{target.ptvalue} INDDIR)!"
|
26
|
+
combatant.hit_target(target)
|
27
|
+
combatant.inddir += target.ptvalue
|
28
|
+
puts combatant
|
29
|
+
else
|
30
|
+
puts "#{combatant.nation} whiffed it!"
|
31
|
+
combatant.megatonnage -= 5
|
32
|
+
puts combatant
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# def milabbrevs
|
38
|
+
# puts "MILABBREVS(Military Abbreviations)......."
|
39
|
+
# puts "CONFORCON: Conventional Force Concentrations"
|
40
|
+
# puts "INDDIR: Infliction of Death, Destruction and Incapacitation of Response"
|
41
|
+
# puts "MAMA: Major Metropolitan Areas"
|
42
|
+
# puts "MIRV: Multiple Independent Reentry Vehicles"
|
43
|
+
# puts "SACPOP: Strikes Against Civilian Populations"
|
44
|
+
# puts "SPASEX: Spasm Exchanges"
|
45
|
+
# puts "SSTRAC: Sites of Strategic Command"
|
46
|
+
# puts "SUFDDIR: Suffering of Death, Destruction and Incapacitation of Response"
|
47
|
+
# end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Eschaton
|
2
|
+
|
3
|
+
Target = Struct.new(:name, :ptvalue)
|
4
|
+
|
5
|
+
module StrategicTargets
|
6
|
+
|
7
|
+
|
8
|
+
TARGETS = [
|
9
|
+
Target.new("MAMA", 100),
|
10
|
+
Target.new("CONFORCON", 50),
|
11
|
+
Target.new("SSTRAC", 100),
|
12
|
+
Target.new("submarine", 15),
|
13
|
+
Target.new("airfield", 20),
|
14
|
+
Target.new("bridge", 5),
|
15
|
+
Target.new("satellite facility", 25),
|
16
|
+
Target.new("carrier group", 28),
|
17
|
+
Target.new("power plant", 35),
|
18
|
+
Target.new("rail convergence", 23),
|
19
|
+
Target.new("atomic plant", 45),
|
20
|
+
Target.new("plutonium uranium enrichment plant", 50),
|
21
|
+
Target.new("diffusion plant", 55),
|
22
|
+
Target.new("breeder reactor", 51),
|
23
|
+
Target.new("initiator factory", 38),
|
24
|
+
Target.new("neutron lab", 40),
|
25
|
+
Target.new("tritium reactor", 35),
|
26
|
+
Target.new("heavy water plant", 26),
|
27
|
+
Target.new("semiprivate concern", 20),
|
28
|
+
Target.new("linear accelerator", 30),
|
29
|
+
Target.new("annular fusion lab", 85),
|
30
|
+
Target.new("antimissile base", 40),
|
31
|
+
Target.new("silo cluster", 42),
|
32
|
+
Target.new("b2 squadron", 38)
|
33
|
+
]
|
34
|
+
|
35
|
+
# def self.select(target)
|
36
|
+
# if Targets.any? { |i| i.name == target }
|
37
|
+
# @target = Targets.find {|x| x.name == target }
|
38
|
+
# else
|
39
|
+
# puts "\nPlease Enter the name of a Target:\n "
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
|
43
|
+
def self.random
|
44
|
+
TARGETS.sample
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'eschaton/combatant'
|
2
|
+
|
3
|
+
|
4
|
+
describe Eschaton::Combatant do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@pemulis = Eschaton::Combatant.new('peemster')
|
8
|
+
@hal = Eschaton::Combatant.new('halsadick')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "but so like, has an upcased nation abbreviation" do
|
12
|
+
expect(@hal.nation).to eq('HALSADICK')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has an initial megatonnage" do
|
16
|
+
expect(@hal.megatonnage).to be >= 0
|
17
|
+
end
|
18
|
+
|
19
|
+
it "loses megatonnage when launching an attack" do
|
20
|
+
@pemulis.mirv(@hal)
|
21
|
+
expect(@pemulis.megatonnage).to eq(100)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has a total score that stems from the ratio of INDDIR and SUFDDIR" do
|
25
|
+
@hal.mirv(@pemulis)
|
26
|
+
@pemulis.sacpop(@hal)
|
27
|
+
expect(@hal.scoretotal).to eq(7)
|
28
|
+
end
|
29
|
+
|
30
|
+
# it "will cause opponent comm loss if successfully launching an EM-Pulse"
|
31
|
+
|
32
|
+
|
33
|
+
# it "should not have DEFCON levels lower than 1"
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'eschaton/game'
|
2
|
+
|
3
|
+
describe Eschaton::Game do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@eschaton = Eschaton::Game.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# context "being played" do
|
10
|
+
# before do
|
11
|
+
# @combatant = Eschaton.combatants.sample
|
12
|
+
# end
|
13
|
+
|
14
|
+
# it "critical hit if higher accuracy" do
|
15
|
+
# GameMaster.stub(:accuracy) {19}
|
16
|
+
# @eschaton.play(2)
|
17
|
+
# expect(combatant.inddir).to eq((inddir + 50) * 2)
|
18
|
+
# end
|
19
|
+
|
20
|
+
# it "normal damage if medium accuracy" do
|
21
|
+
# GameMaster.stub(:accuracy) {10}
|
22
|
+
# @eschaton.play(2)
|
23
|
+
# expect(@combatant.inddir).to eq((@inddir + 30) * 2)
|
24
|
+
# end
|
25
|
+
|
26
|
+
# it "misses if a low accuracy" do
|
27
|
+
# GameMaster.stub(:accuracy) {3}
|
28
|
+
# @eschaton.play(2)
|
29
|
+
# expect(@combatant.inddir).to eq(0)
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
|
33
|
+
# context "all Combatants at DEFCON 1" do
|
34
|
+
|
35
|
+
# before do
|
36
|
+
# @eschaton.combatants.map! { |c| c.defcon = 1 }
|
37
|
+
# end
|
38
|
+
|
39
|
+
# it "changes game beanie status to 'UTTER GLOBAL CRISIS'" do
|
40
|
+
# expect(@eschaton.beanie_status).to eq('UTTER GLOBAL CRISIS')
|
41
|
+
# end
|
42
|
+
|
43
|
+
# end
|
44
|
+
|
45
|
+
# it "should have a minimum of 3 rounds"
|
46
|
+
|
47
|
+
# it "should have a maximum of 400 5-megaton warheads to distribute"
|
48
|
+
|
49
|
+
# it "should distribute megatonnage to combatants"
|
50
|
+
|
51
|
+
# it "should have a beanie status to start the game"
|
52
|
+
|
53
|
+
# "eschaton beanie status at 'Cessation of Hostilities'"
|
54
|
+
|
55
|
+
# "eschaton beanie status at 'Utter Global Crisis'"
|
56
|
+
|
57
|
+
# it "should raise all combatants DEFCON levels to 1"
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'eschaton/strategic_targets'
|
2
|
+
|
3
|
+
|
4
|
+
describe Eschaton::Target do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@target = Eschaton::Target.new("MAMA", 50)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has a name attribute" do
|
11
|
+
expect(@target.name).to eql("MAMA")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a points attribute" do
|
15
|
+
expect(@target.ptvalue).to eq(50)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eschaton
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Parr
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: |-
|
28
|
+
# Eschaton for Ruby
|
29
|
+
|
30
|
+
|
31
|
+
An attempt to adapt the game of Eschaton, from David Foster Wallace's [*Infinite Jest*](http://en.wikipedia.org/wiki/Infinite_Jest), into a text-based Ruby game. Definitely a work in progress. Not much to look at now, but I'll update the README when the game gets a little more involved.
|
32
|
+
|
33
|
+
|
34
|
+
To install:
|
35
|
+
|
36
|
+
gem install eschaton
|
37
|
+
|
38
|
+
To play:
|
39
|
+
|
40
|
+
eschaton
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
License
|
46
|
+
----
|
47
|
+
|
48
|
+
MIT
|
49
|
+
|
50
|
+
Copyright (c) 2014, Sean Parr
|
51
|
+
|
52
|
+
Eschaton is provided as-is under the MIT license. For more information see LICENSE.
|
53
|
+
email: seancparr@gmail.com
|
54
|
+
executables:
|
55
|
+
- eschaton
|
56
|
+
extensions: []
|
57
|
+
extra_rdoc_files: []
|
58
|
+
files:
|
59
|
+
- LICENSE.md
|
60
|
+
- README.md
|
61
|
+
- bin/eschaton
|
62
|
+
- lib/eschaton/combatant.rb
|
63
|
+
- lib/eschaton/game.rb
|
64
|
+
- lib/eschaton/gamemaster.rb
|
65
|
+
- lib/eschaton/strategic_targets.rb
|
66
|
+
- spec/eschaton/combatant_spec.rb
|
67
|
+
- spec/eschaton/game_spec.rb
|
68
|
+
- spec/eschaton/strategic_targets_spec.rb
|
69
|
+
homepage: https://github.com/rubyruettiger
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.9'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 2.2.1
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Play text game Eschaton
|
93
|
+
test_files:
|
94
|
+
- spec/eschaton/combatant_spec.rb
|
95
|
+
- spec/eschaton/game_spec.rb
|
96
|
+
- spec/eschaton/strategic_targets_spec.rb
|