smack_engine 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/smack_engine.rb +14 -0
- data/lib/smack_engine/cache.rb +15 -0
- data/lib/smack_engine/card.rb +22 -0
- data/lib/smack_engine/controller.rb +92 -0
- data/lib/smack_engine/deck.rb +12 -0
- data/lib/smack_engine/game_resolver.rb +46 -0
- data/lib/smack_engine/game_rules.rb +3 -0
- data/lib/smack_engine/game_state.rb +30 -0
- data/lib/smack_engine/io.rb +18 -0
- data/lib/smack_engine/player.rb +18 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c7c4e50efbe47d2ab9915687ca010ce6d2f35087
|
4
|
+
data.tar.gz: f3ca15482f06974c3391a54ed916ea3c67f5d987
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc5215dd6f4b80e982944423d16518b30ca5f1ae2e5612728b8a5c182dcd770a994aca456d6e027efd0af64c357b89cdeee40f93caea3ce05f50379b47e0ba9b
|
7
|
+
data.tar.gz: b0813b73ac38610d46a1eacf5ad45a6e6f6da0318e4f39f29292b0fc89495fb0a7a78441a3031f091e6be4c0bb0b3a5069ab6648366613b48b1ded7634233176
|
data/lib/smack_engine.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module GameEngine
|
2
|
+
end
|
3
|
+
|
4
|
+
|
5
|
+
require 'smack_engine/game_rules'
|
6
|
+
require 'smack_engine/cache'
|
7
|
+
require 'smack_engine/card'
|
8
|
+
require 'smack_engine/controller'
|
9
|
+
require 'smack_engine/deck'
|
10
|
+
require 'smack_engine/game_resolver'
|
11
|
+
require 'smack_engine/game_state'
|
12
|
+
require 'smack_engine/io'
|
13
|
+
require 'smack_engine/player'
|
14
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module GameEngine
|
2
|
+
module Cache
|
3
|
+
def self.save_game_state(game, caching_interface)
|
4
|
+
caching_interface.write "#{game.id}#{game.player_one.id}#{game.player_two.id}", game
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.fetch_game_state(game_data, caching_interface)
|
8
|
+
caching_interface.read "#{game_data.id}#{game_data.player_one.id}#{game_data.player_two.id}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.clear_game_state(game_data, caching_interface)
|
12
|
+
caching_interface.delete "#{game_data.id}#{game_data.player_one.id}#{game_data.player_two.id}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GameEngine
|
2
|
+
class Card
|
3
|
+
attr_reader :id, :card_type, :name, :description, :strength, :intelligence, :charisma, :time_period
|
4
|
+
|
5
|
+
def initialize(card_data)
|
6
|
+
@id = card_data.id
|
7
|
+
@type = card_data.card_type
|
8
|
+
@name = card_data.name
|
9
|
+
@description = card_data.description
|
10
|
+
@strength = card_data.strength
|
11
|
+
@intelligence = card_data.intelligence
|
12
|
+
@charisma = card_data.charisma
|
13
|
+
@time_period = card_data.time_period
|
14
|
+
@picture_url = card_data.picture_url
|
15
|
+
end
|
16
|
+
|
17
|
+
def max_stat
|
18
|
+
[strength,intelligence,charisma].max
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module GameEngine
|
2
|
+
module Controller
|
3
|
+
|
4
|
+
def self.save_game_state(game_state, caching_interface)
|
5
|
+
GameEngine::Cache.save_game_state(game_state, caching_interface)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.fetch_game_state(game_data, caching_interface)
|
9
|
+
GameEngine::Cache.fetch_game_state(game_data, caching_interface)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.update_game_state_time(game_state)
|
13
|
+
game_state.time = Time.now
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.output_player_data(game_state, player_id)
|
17
|
+
GameEngine::IO.output_player_data(game_state, player_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.selection_made?(player)
|
21
|
+
!player.selection.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.updatetime_savegamestate_and_outputplayerdata(game_state, player_id, caching_interface)
|
25
|
+
update_game_state_time(game_state)
|
26
|
+
save_game_state(game_state, caching_interface)
|
27
|
+
output_player_data(game_state, player_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.phase_time_check(game_state, time_input)
|
31
|
+
Time.now - game_state.time >= GAME_RULES[time_input]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.both_players_moved?(game_state)
|
35
|
+
selection_made?(game_state.player_one) && selection_made?(game_state.player_two)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.advance_game(game_data, player_id, caching_interface)
|
39
|
+
# This method is responsible for switching phases inside of the GameEngine::Game
|
40
|
+
# class when passed the ActiveRecord model of the game and the player_id for the
|
41
|
+
# client that's making the request.
|
42
|
+
game_state = GameEngine::Cache.fetch_game_state(game_data, caching_interface)
|
43
|
+
current_time = Time.now
|
44
|
+
|
45
|
+
current_player = game_state.target_player(player_id.to_i)
|
46
|
+
player_one = game_state.player_one
|
47
|
+
player_two = game_state.player_two
|
48
|
+
|
49
|
+
case game_state.phase
|
50
|
+
when :setup
|
51
|
+
if phase_time_check(game_state, :setup_time)
|
52
|
+
game_state.phase = :move
|
53
|
+
GameEngine::GameResolver.deal_cards(game_state)
|
54
|
+
updatetime_savegamestate_and_outputplayerdata(game_state, player_id, caching_interface)
|
55
|
+
|
56
|
+
end
|
57
|
+
when :move
|
58
|
+
if phase_time_check(game_state, :move_time) && !selection_made?(current_player)
|
59
|
+
current_player.selection << nil
|
60
|
+
save_game_state(game_state, caching_interface)
|
61
|
+
output_player_data(game_state, player_id)
|
62
|
+
end
|
63
|
+
|
64
|
+
if both_players_moved?(game_state)
|
65
|
+
game_state.phase = :resolution
|
66
|
+
updatetime_savegamestate_and_outputplayerdata(game_state, player_id, caching_interface)
|
67
|
+
end
|
68
|
+
when :won
|
69
|
+
output_player_data(game_state, player_id)
|
70
|
+
else
|
71
|
+
if phase_time_check(game_state, :resolution_time)
|
72
|
+
GameEngine::GameResolver.resolve_round(game_state)
|
73
|
+
unless game_state.won?
|
74
|
+
game_state.round += 1
|
75
|
+
game_state.phase = :move
|
76
|
+
GameEngine::GameResolver.deal_cards(game_state)
|
77
|
+
end
|
78
|
+
save_game_state(game_state, caching_interface)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
output_player_data(game_state, player_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.get_player_move(game_data, player_id, card_id, caching_interface)
|
85
|
+
game_state = GameEngine::Cache.fetch_game_state(game_data, caching_interface)
|
86
|
+
if game_state.target_player(player_id).selection.empty? && game_state.phase == :move
|
87
|
+
GameEngine::IO.input_player_move(game_state, player_id, card_id)
|
88
|
+
save_game_state(game_state, caching_interface)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module GameEngine
|
2
|
+
module GameResolver
|
3
|
+
def self.resolve_round(game_state)
|
4
|
+
@player_one = game_state.player_one
|
5
|
+
@player_two = game_state.player_two
|
6
|
+
|
7
|
+
calc_points
|
8
|
+
reset_selections
|
9
|
+
game_state.phase = :won if game_state.won?
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.determine_maxstat(player)
|
13
|
+
player.selection.first.nil? ? 0 : player.selection.first.max_stat
|
14
|
+
end
|
15
|
+
|
16
|
+
#if player one has a higher maxstat, the overall damage value returned is positive. If player two has a higher maxstat, the overall damage value returned is negative.
|
17
|
+
def self.damage
|
18
|
+
determine_maxstat(@player_one) - determine_maxstat(@player_two)
|
19
|
+
end
|
20
|
+
|
21
|
+
#Calc_points should work when the damage value returned from damage above is negative (when player two has a higher maxstat) or positive (when player one has a higher maxstat). (For example, consider that the subtraction of a negative value adds a positive value and the addition of negative value subtracts that value.)
|
22
|
+
def self.calc_points
|
23
|
+
@player_one.points += damage
|
24
|
+
@player_two.points -= damage
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.reset_selections
|
28
|
+
@player_one.selection = []
|
29
|
+
@player_two.selection = []
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.deal_cards(game_state)
|
33
|
+
player_one = game_state.player_one
|
34
|
+
player_two = game_state.player_two
|
35
|
+
|
36
|
+
until player_one.hand.size == GAME_RULES[:hand_size]
|
37
|
+
player_one.hand << player_one.deck.list.pop
|
38
|
+
end
|
39
|
+
|
40
|
+
until player_two.hand.size == GAME_RULES[:hand_size]
|
41
|
+
player_two.hand << player_two.deck.list.pop
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GameEngine
|
2
|
+
class GameState
|
3
|
+
attr_reader :id, :player_one, :player_two
|
4
|
+
attr_accessor :round, :time, :phase
|
5
|
+
|
6
|
+
def initialize(game_data)
|
7
|
+
@id = game_data.id
|
8
|
+
@player_one = GameEngine::Player.new(game_data.player_one)
|
9
|
+
@player_two = GameEngine::Player.new(game_data.player_two)
|
10
|
+
@round = 0
|
11
|
+
@phase = :setup
|
12
|
+
@time = Time.now
|
13
|
+
end
|
14
|
+
|
15
|
+
def target_player(player_id)
|
16
|
+
return player_one if player_one.id.to_i == player_id.to_i
|
17
|
+
return player_two if player_two.id.to_i == player_id.to_i
|
18
|
+
raise ArgumentError.new("No player found with id = #{player_id}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def winner
|
22
|
+
return player_one if player_one.points > 0 && player_two.points <= 0
|
23
|
+
return player_two if player_two.points > 0 && player_one.points <= 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def won?
|
27
|
+
winner != nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module GameEngine
|
2
|
+
module IO
|
3
|
+
def self.output_player_data(game_state, player_id)
|
4
|
+
time_remaining = (Time.now - game_state.time).to_i
|
5
|
+
|
6
|
+
case player_id
|
7
|
+
when game_state.player_one.id
|
8
|
+
return { player_hand: game_state.player_one.hand, player_points: game_state.player_one.points, round: game_state.round, phase: game_state.phase, time_remaining: time_remaining }
|
9
|
+
when game_state.player_two.id
|
10
|
+
return { player_hand: game_state.player_two.hand, player_points: game_state.player_two.points, round: game_state.round, phase: game_state.phase, time_remaining: time_remaining }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.input_player_move(game_state, player_id, card_id)
|
15
|
+
game_state.target_player(player_id).play_cards([card_id])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module GameEngine
|
2
|
+
class Player
|
3
|
+
attr_reader :id, :deck, :hand
|
4
|
+
attr_accessor :points, :selection
|
5
|
+
|
6
|
+
def initialize(player_data)
|
7
|
+
@id = player_data.id
|
8
|
+
@deck = GameEngine::Deck.new(player_data.deck)
|
9
|
+
@hand = []
|
10
|
+
@selection = []
|
11
|
+
@points = GameEngine::GAME_RULES[:starting_points]
|
12
|
+
end
|
13
|
+
|
14
|
+
def play_cards(indexes)
|
15
|
+
indexes.each { |i| selection << hand.delete_at(i) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smack_engine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Beatrix Carroll
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: The game engine for the game that was initially and affectionately known
|
14
|
+
as Smackwangler.
|
15
|
+
email: beatrixcarroll@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/smack_engine.rb
|
21
|
+
- lib/smack_engine/game_rules.rb
|
22
|
+
- lib/smack_engine/cache.rb
|
23
|
+
- lib/smack_engine/card.rb
|
24
|
+
- lib/smack_engine/controller.rb
|
25
|
+
- lib/smack_engine/deck.rb
|
26
|
+
- lib/smack_engine/game_resolver.rb
|
27
|
+
- lib/smack_engine/game_state.rb
|
28
|
+
- lib/smack_engine/io.rb
|
29
|
+
- lib/smack_engine/player.rb
|
30
|
+
homepage: http://rubygems.org/gems/hola
|
31
|
+
licenses:
|
32
|
+
- MIT
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 2.0.14
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: Smackwangler!
|
54
|
+
test_files: []
|