Skip to content

Commit

Permalink
Make Hungry Hungry Baubles a Basic Game (Resolves #118)
Browse files Browse the repository at this point in the history
Created Common 'BaubleGame' Base Class for Hungry Hungry Baubles and Bauble Hunt.
Made Bauble Hunt and Discovery Quest use new BasicGame's getObjectiveLocation() instead of getHomeBasePosition().
  • Loading branch information
hawkerm committed May 11, 2016
1 parent d702608 commit 85d8810
Show file tree
Hide file tree
Showing 26 changed files with 228 additions and 215 deletions.
86 changes: 86 additions & 0 deletions SBA_Serv/Game/BaubleGame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Space Battle Arena is a Programming Game.
Copyright (C) 2012-2016 Michael A. Hawker and Brett Wortzman
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The full text of the license is available online: http://opensource.org/licenses/GPL-2.0
"""

from Game import BasicGame
from GUI.ObjWrappers.GUIEntity import GUIEntity
from GUI.GraphicsCache import Cache
from World.WorldMath import intpos, friendly_type, PlayerStat, aligninstances, getPositionAwayFromOtherObjects
from World.Entities import PhysicalRound, Entity
import random
import logging
import pygame
from operator import attrgetter

class BaseBaubleGame(BasicGame):
"""
Base Class for Creating Bauble Games which spawn Baubles of various colors/point values.
Used by Hungry Hungry Baubles Basic Game and Advanced Bauble Hunt game.
"""
VALUE_TABLE = []

def __init__(self, cfgobj):
bb = cfgobj.getfloat("BaubleGame", "bauble_percent_blue")
yb = cfgobj.getfloat("BaubleGame", "bauble_percent_yellow")
rb = cfgobj.getfloat("BaubleGame", "bauble_percent_red")
BaseBaubleGame.VALUE_TABLE = [(bb, cfgobj.getint("BaubleGame", "bauble_points_blue")), (bb+yb, cfgobj.getint("BaubleGame", "bauble_points_yellow")), (bb+yb+rb, cfgobj.getint("BaubleGame", "bauble_points_red"))]

super(BaseBaubleGame, self).__init__(cfgobj)

class BaubleWrapper(GUIEntity):
def __init__(self, obj, world):
super(BaubleWrapper, self).__init__(obj, world)
self.surface = Cache().getImage("Games/Bauble" + str(obj.value))

def draw(self, surface, flags):
surface.blit(self.surface, intpos((self._worldobj.body.position[0] - 8, self._worldobj.body.position[1] - 8)))

super(BaubleWrapper, self).draw(surface, flags)

class Bauble(PhysicalRound):
WRAPPERCLASS = BaubleWrapper
"""
Baubles are small prizes worth different amounts of points
"""
def __init__(self, pos, value=1):
super(Bauble, self).__init__(8, 2000, pos)
self.shape.elasticity = 0.8
self.health = PlayerStat(0)

self.shape.group = 1

self.value = value

def collide_start(self, otherobj):
return False

def getExtraInfo(self, objData, player):
objData["VALUE"] = self.value

@staticmethod
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("Bauble", "buffer_object"), cfg.getint("Bauble", "buffer_edge"))

# Get value within tolerances
r = random.random()
v = 0
for ent in BaseBaubleGame.VALUE_TABLE:
if r < ent[0]:
v = ent[1]
break

b = Bauble(pos, v)
world.append(b)
return b
58 changes: 3 additions & 55 deletions SBA_Serv/Game/BaubleHunt.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
The full text of the license is available online: http://opensource.org/licenses/GPL-2.0
"""

from Game import BasicGame
from BaubleGame import *
from Utils import CallbackTimer
from World.Entities import Entity, PhysicalRound
from World.WorldEntities import Ship
Expand All @@ -27,15 +27,11 @@
import thread
from operator import attrgetter

class BaubleHuntGame(BasicGame):
class BaubleHuntGame(BaseBaubleGame):
VALUE_TABLE = []

def __init__(self, cfgobj):
bb = cfgobj.getfloat("BaubleHunt", "bauble_percent_blue")
yb = cfgobj.getfloat("BaubleHunt", "bauble_percent_yellow")
rb = cfgobj.getfloat("BaubleHunt", "bauble_percent_red")
self._mv = cfgobj.getint("BaubleHunt", "bauble_points_red")
BaubleHuntGame.VALUE_TABLE = [(bb, cfgobj.getint("BaubleHunt", "bauble_points_blue")), (bb+yb, cfgobj.getint("BaubleHunt", "bauble_points_yellow")), (bb+yb+rb, self._mv)]
self._mv = cfgobj.getint("BaubleGame", "bauble_points_red")

self._respawn = cfgobj.getboolean("BaubleHunt", "respawn_bauble_on_collect")

Expand Down Expand Up @@ -203,54 +199,6 @@ def round_start(self):

super(BaubleHuntGame, self).round_start()


class BaubleWrapper(GUIEntity):
def __init__(self, obj, world):
super(BaubleWrapper, self).__init__(obj, world)
self.surface = Cache().getImage("Games/Bauble" + str(obj.value))

def draw(self, surface, flags):
surface.blit(self.surface, intpos((self._worldobj.body.position[0] - 8, self._worldobj.body.position[1] - 8)))

super(BaubleWrapper, self).draw(surface, flags)

class Bauble(PhysicalRound):
WRAPPERCLASS = BaubleWrapper
"""
Baubles are small prizes worth different amounts of points
"""
def __init__(self, pos, value=1):
super(Bauble, self).__init__(8, 2000, pos)
self.shape.elasticity = 0.8
self.health = PlayerStat(0)

self.shape.group = 1

self.value = value

def collide_start(self, otherobj):
return False

def getExtraInfo(self, objData, player):
objData["VALUE"] = self.value

@staticmethod
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("Bauble", "buffer_object"), cfg.getint("Bauble", "buffer_edge"))

# Get value within tolerances
r = random.random()
v = 0
for ent in BaubleHuntGame.VALUE_TABLE:
if r < ent[0]:
v = ent[1]
break

b = Bauble(pos, v)
world.append(b)
return b

class OutpostWrapper(GUIEntity):
def __init__(self, obj, world):
super(OutpostWrapper, self).__init__(obj, world)
Expand Down
2 changes: 1 addition & 1 deletion SBA_Serv/Game/DiscoveryQuest.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def game_get_extra_environment(self, player):
env = super(DiscoveryQuestGame, self).game_get_extra_environment(player)

if player.outpost != None:
env["OUTPOST"] = intpos(player.outpost.body.position)
env["POSITION"] = intpos(player.outpost.body.position)
env["FAILED"] = player.failed
env["MISSION"] = player.mission
obj = player.object
Expand Down
2 changes: 1 addition & 1 deletion SBA_Serv/Game/Game.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ def player_update_score(self, player, amount):
if player.score < 0:
player.score = 0

# TODO: should probably check if primary highest flag to see if we want to keep track of lowest or highest score here
# TODO: #118 should probably check if primary highest flag to see if we want to keep track of lowest or highest score here
# update if this is a new personal best
if player.score > player.bestscore:
player.bestscore = player.score
Expand Down
75 changes: 17 additions & 58 deletions SBA_Serv/Game/HungryHungryBaubles.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,31 @@
The full text of the license is available online: http://opensource.org/licenses/GPL-2.0
"""

from Game import BasicGame
from BaubleGame import *
from Utils import CallbackTimer
from World.Entities import PhysicalRound, Entity
from World.WorldEntities import Ship
from GUI.ObjWrappers.GUIEntity import GUIEntity
from World.WorldMath import intpos, friendly_type, PlayerStat, aligninstances, getPositionAwayFromOtherObjects
from GUI.GraphicsCache import Cache
from GUI.Helpers import debugfont
import logging
import pygame
from operator import attrgetter

class HungryHungryBaublesGame(BasicGame):
class HungryHungryBaublesGame(BaseBaubleGame):

def __init__(self, cfgobj):
self.__points_blue = cfgobj.getint("HungryHungryBaubles", "bauble_points_blue")
self.__points_gold = cfgobj.getint("HungryHungryBaubles", "bauble_points_gold")
self.__points_blue = cfgobj.getint("BaubleGame", "bauble_points_blue")
self.__points_gold = cfgobj.getint("BaubleGame", "bauble_points_yellow")
self.__points_extra = cfgobj.getint("HungryHungryBaubles", "bauble_points_extra")
self.__assign_specific_bauble = cfgobj.getboolean("HungryHungryBaubles", "assign_specific_bauble")

self.__baubles = {}

super(HungryHungryBaublesGame, self).__init__(cfgobj)

def game_get_info(self):
return {"GAMENAME": "HungryHungryBaubles"}

def player_added(self, player, reason):
if reason == BasicGame._ADD_REASON_START_:
self.__addBauble(player) # Add Home Base
if reason == BasicGame._ADD_REASON_START_ and self.__assign_specific_bauble:
self.__addBauble(player) # Add Golden Bauble

super(HungryHungryBaublesGame, self).player_added(player, reason)

Expand All @@ -65,13 +61,13 @@ def world_physics_pre_collision(self, obj1, obj2):
def collectBaubles(self, ship, bauble):
logging.info("Collected Baubles Ship #%d", ship.id)
# collect own Bauble?
if bauble == self.__baubles[ship.player.netid]:
if self.__assign_specific_bauble and bauble == self.__baubles[ship.player.netid]:
logging.info("Collected Own Bauble #%d", ship.id)
self.player_update_score(ship.player, self.__points_extra)
ship.player.sound = "COLLECT"
# add new bauble
self.__addBauble(ship.player, True)
elif bauble in self.__baubles.values():
elif self.__assign_specific_bauble and bauble in self.__baubles.values():
logging.info("Collected Gold Bauble #%d", ship.id)
# someone else's bauble
for key, value in self.__baubles.iteritems():
Expand All @@ -94,52 +90,15 @@ def collectBaubles(self, ship, bauble):

def game_get_extra_environment(self, player):
env = super(HungryHungryBaublesGame, self).game_get_extra_environment(player)
env["POSITION"] = intpos(self.__baubles[player.netid].body.position)
if self.__assign_specific_bauble:
env["POSITION"] = intpos(self.__baubles[player.netid].body.position)

return env

def gui_draw_game_world_info(self, surface, flags, trackplayer):
for player in self.game_get_current_player_list():
obj = player.object
if obj != None and self.__baubles.has_key(player.netid):
# draw line between player and Bauble
pygame.draw.line(surface, player.color, intpos(obj.body.position), intpos(self.__baubles[player.netid].body.position))

class BaubleWrapper(GUIEntity):
def __init__(self, obj, world):
super(BaubleWrapper, self).__init__(obj, world)
self.surface = Cache().getImage("Games/Bauble" + str(obj.value))

def draw(self, surface, flags):
# Check if Thrusting or Braking
surface.blit(self.surface, intpos((self._worldobj.body.position[0] - 8, self._worldobj.body.position[1] - 8)))

super(BaubleWrapper, self).draw(surface, flags)

class Bauble(PhysicalRound):
WRAPPERCLASS = BaubleWrapper
"""
Baubles are small prizes worth different amounts of points
"""
def __init__(self, pos, value=1):
super(Bauble, self).__init__(8, 2000, pos)
self.shape.elasticity = 0.8
self.health = PlayerStat(0)

self.shape.group = 1

self.value = value

def collide_start(self, otherobj):
return False

def getExtraInfo(self, objData, player):
objData["VALUE"] = self.value

@staticmethod
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("Bauble", "buffer_object"), cfg.getint("Bauble", "buffer_edge"))
b = Bauble(pos, cfg.getint("HungryHungryBaubles", "bauble_points_blue"))
world.append(b)
return b
if self.__assign_specific_bauble:
for player in self.game_get_current_player_list():
obj = player.object
if obj != None and self.__baubles.has_key(player.netid):
# draw line between player and Bauble
pygame.draw.line(surface, player.color, intpos(obj.body.position), intpos(self.__baubles[player.netid].body.position))
2 changes: 1 addition & 1 deletion SBA_Serv/Game/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__all__ = ["Game", "Players", "Utils", "Tournaments"]
__all__ = ["Game", "BaubleGame", "Players", "Utils", "Tournaments"]
5 changes: 4 additions & 1 deletion SBA_Serv/SBA_Serv.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="compile.py" />
<Compile Include="Game\BaubleGame.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="Game\BaubleHunt.py" />
<Compile Include="Game\DiscoveryQuest.py">
<SubType>Code</SubType>
Expand Down Expand Up @@ -138,7 +141,7 @@
<Content Include="basicgame_asteroid.cfg" />
<Content Include="basicgame_survivor.cfg" />
<Content Include="empty.cfg" />
<Content Include="game_hungryhungrybaubles.cfg" />
<Content Include="basicgame_hungryhungrybaubles.cfg" />
<Content Include="game_kingofspace.cfg" />
<Content Include="game_discoveryquest.cfg" />
<Content Include="game_kingofthebubble.cfg" />
Expand Down
2 changes: 1 addition & 1 deletion SBA_Serv/Tests/BaubleHuntTestCases.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_points_on_pickup(self):
time.sleep(0.5)

self.assertEqual(len(ship.player.carrying), 0, "Player didn't drop off baubles")
self.assertEqual(ship.player.score, self.cfg.getint("BaubleHunt", "bauble_points_blue") + self.cfg.getint("BaubleHunt", "bauble_points_yellow") + self.cfg.getint("BaubleHunt", "bauble_points_red"), "Player didn't earn bauble points")
self.assertEqual(ship.player.score, self.cfg.getint("BaubleGame", "bauble_points_blue") + self.cfg.getint("BaubleGame", "bauble_points_yellow") + self.cfg.getint("BaubleGame", "bauble_points_red"), "Player didn't earn bauble points")
self.assertGreater(len(self.game.world), 7, "Baubles not respawned")


Expand Down
6 changes: 3 additions & 3 deletions SBA_Serv/Tests/HungryHungryBaublesTestCases.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ def test_points_on_pickup(self):

time.sleep(5)

self.assertEqual(ship.player.score, self.cfg.getint("HungryHungryBaubles", "bauble_points_blue"), "Player didn't earn point")
self.assertEqual(ship.player.score, self.cfg.getint("BaubleGame", "bauble_points_blue"), "Player didn't earn point")

time.sleep(6)

self.assertEqual(ship.player.score, self.cfg.getint("HungryHungryBaubles", "bauble_points_blue") + self.cfg.getint("HungryHungryBaubles", "bauble_points_gold"), "Player didn't earn point gold")
self.assertEqual(ship.player.score, self.cfg.getint("BaubleGame", "bauble_points_blue") + self.cfg.getint("BaubleGame", "bauble_points_yellow"), "Player didn't earn point gold")

time.sleep(0.5)
# move to golden bauble position
Expand All @@ -97,7 +97,7 @@ def test_points_on_pickup(self):

time.sleep(0.5)

self.assertEqual(ship.player.score, self.cfg.getint("HungryHungryBaubles", "bauble_points_blue") + self.cfg.getint("HungryHungryBaubles", "bauble_points_gold") * 2 + self.cfg.getint("HungryHungryBaubles", "bauble_points_extra"), "Player didn't earn golden bauble points")
self.assertEqual(ship.player.score, self.cfg.getint("BaubleGame", "bauble_points_blue") + self.cfg.getint("BaubleGame", "bauble_points_yellow") * 2 + self.cfg.getint("HungryHungryBaubles", "bauble_points_extra"), "Player didn't earn golden bauble points")

time.sleep(0.5)

Expand Down
8 changes: 4 additions & 4 deletions SBA_Serv/Tests/test_baublehunt.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ spawn_time_max = 6
game = BaubleHunt
secondary_victory_attr = totalcollected

[BaubleHunt]
ship_cargo_size = 5
respawn_bauble_on_collect = true

[BaubleGame]
bauble_percent_blue = 0.6
bauble_points_blue = 1

Expand All @@ -27,3 +24,6 @@ bauble_points_yellow = 3
bauble_percent_red = 0.1
bauble_points_red = 5

[BaubleHunt]
ship_cargo_size = 5
respawn_bauble_on_collect = true
Loading

0 comments on commit 85d8810

Please sign in to comment.