Skip to content

Commit

Permalink
Merge pull request #238 from johnpooch/develop
Browse files Browse the repository at this point in the history
0.4
  • Loading branch information
johnpooch authored Apr 28, 2021
2 parents caf2cee + 81a58bf commit 32bcab6
Show file tree
Hide file tree
Showing 26 changed files with 502 additions and 135 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

A web browser version of the classic strategy board game Diplomacy.

We are massive fans of the game and have been happily using some of the
We are fans of the game and enjoy playing on the
existing web versions like [Play Diplomacy][play diplomacy],
[Backstabbr][backstabbr], and others for years. We decided to build a new
[Backstabbr][backstabbr], and others. We decided to build a new
version of the game to try to bring together and improve on some of the
features of the existing versions. We also wanted to make the project open
source so that it could be maintained by an enthusiastic community of diplomacy
Expand Down
7 changes: 6 additions & 1 deletion adjudicator/named_coast.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ class NamedCoast:

@register
def __init__(self, state, id, name, parent, neighbours):
self.state = state
self.id = id
self.name = name
self.parent = parent
self.neighbours = neighbours
self.neighbour_ids = neighbours

def __str__(self):
return f"{self.parent.name} ({self.name})"

@property
def neighbours(self):
return [t for t in self.state.territories if t.id in self.neighbour_ids]
3 changes: 3 additions & 0 deletions adjudicator/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ def process(state):
# Find all pieces that are not dislodged
non_dislodged_pieces = [p for p in state.pieces if not p.dislodged]
for piece in non_dislodged_pieces:
# Ignore pieces that move successfully
if piece.order.is_move and piece.order.outcome == Outcomes.SUCCEEDS:
continue
if piece.nation != getattr(piece.territory, 'controlled_by', False):
if not (piece.territory.is_sea):
piece.territory.captured_by = piece.nation
Expand Down
26 changes: 13 additions & 13 deletions adjudicator/tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,29 +186,29 @@ def __init__(self, state):
class NamedCoasts:
def __init__(self, state, territories):
self.SPAIN_SC = NamedCoast(state, 1, 'spain sc', territories.SPAIN, [
territories.MARSEILLES, territories.PORTUGAL,
territories.MID_ATLANTIC,
territories.WESTERN_MEDITERRANEAN, territories.GULF_OF_LYON
territories.MARSEILLES.id, territories.PORTUGAL.id,
territories.MID_ATLANTIC.id,
territories.WESTERN_MEDITERRANEAN.id, territories.GULF_OF_LYON.id
])
self.SPAIN_NC = NamedCoast(state, 2, 'spain nc', territories.SPAIN, [
territories.PORTUGAL, territories.MID_ATLANTIC, territories.GASCONY
territories.PORTUGAL.id, territories.MID_ATLANTIC.id, territories.GASCONY.id
])
self.BULGARIA_EC = NamedCoast(state, 3, 'bulgaria ec', territories.BULGARIA, [
territories.BLACK_SEA, territories.RUMANIA,
territories.CONSTANTINOPLE,
territories.BLACK_SEA.id, territories.RUMANIA.id,
territories.CONSTANTINOPLE.id,
])
self.BULGARIA_SC = NamedCoast(state, 4, 'bulgaria sc', territories.BULGARIA, [
territories.CONSTANTINOPLE, territories.AEGEAN_SEA,
territories.GREECE
territories.CONSTANTINOPLE.id, territories.AEGEAN_SEA.id,
territories.GREECE.id
])
self.ST_PETERSBURG_NC = NamedCoast(state, 5, 'st petersburg nc',
territories.ST_PETERSBURG, [
territories.BARRENTS_SEA,
territories.NORWAY
territories.BARRENTS_SEA.id,
territories.NORWAY.id
])
self.ST_PETERSBURG_SC = NamedCoast(state, 6, 'st petersburg nc',
territories.ST_PETERSBURG, [
territories.FINLAND,
territories.LIVONIA,
territories.GULF_OF_BOTHNIA
territories.FINLAND.id,
territories.LIVONIA.id,
territories.GULF_OF_BOTHNIA.id
])
4 changes: 2 additions & 2 deletions adjudicator/tests/test_piece.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def setUp(self):
self.marseilles = CoastalTerritory(self.state, 12, 'Marseilles', 'France', [10], [10])
self.mid_atlantic = SeaTerritory(self.state, 13, 'Mid Atlantic', [10])
self.gulf_of_lyon = SeaTerritory(self.state, 14, 'Gulf of Lyon', [10])
self.spain_north_coast = NamedCoast(self.state, 1, 'North Coast', self.spain, [self.gascony, self.mid_atlantic])
self.spain_south_coast = NamedCoast(self.state, 2, 'South Coast', self.spain, [self.marseilles, self.gulf_of_lyon, self.marseilles])
self.spain_north_coast = NamedCoast(self.state, 1, 'North Coast', self.spain, [self.gascony.id, self.mid_atlantic.id])
self.spain_south_coast = NamedCoast(self.state, 2, 'South Coast', self.spain, [self.marseilles.id, self.gulf_of_lyon.id, self.marseilles.id])

to_register = [self.paris, self.london, self.wales,
self.english_channel, self.brest, self.rome,
Expand Down
7 changes: 7 additions & 0 deletions core/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ def process_turn(turn, dry_run=False):
the turn the adjudicator. Update the turn based on the adjudicator
response.
"""
# Remove pending turnend
try:
turn.turnend.delete()
except models.TurnEnd.DoesNotExist:
pass

logger.info('Processing turn: {}'.format(turn))
turn_data = TurnSerializer(turn).data
outcome = process_game_state(turn_data)
Expand All @@ -40,6 +46,7 @@ def process_turn(turn, dry_run=False):
winning_nation = new_turn.check_for_winning_nation()
if winning_nation:
turn.game.set_winner(winning_nation)

return new_turn


Expand Down
24 changes: 24 additions & 0 deletions core/migrations/0005_auto_20210423_0935.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.1.7 on 2021-04-23 08:35

from django.db import migrations


def add_st_petersburg_to_norway_shared_coasts(apps, schema_editor):
Territory = apps.get_model('core', 'Territory')
st_petersburg = Territory.objects.get(id='standard-st-petersburg')
norway = Territory.objects.get(id='standard-norway')
norway.shared_coasts.add(st_petersburg)


class Migration(migrations.Migration):

dependencies = [
('core', '0004_auto_20210422_1309'),
]

operations = [
migrations.RunPython(
add_st_petersburg_to_norway_shared_coasts,
reverse_code=migrations.RunPython.noop
),
]
24 changes: 24 additions & 0 deletions core/migrations/0006_auto_20210423_1426.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.1.7 on 2021-04-23 13:26

from django.db import migrations


def title_case_named_coast_names(apps, schema_editor):
NamedCoast = apps.get_model('core', 'NamedCoast')
for named_coast in NamedCoast.objects.all():
named_coast.name = named_coast.name.title()
named_coast.save()


class Migration(migrations.Migration):

dependencies = [
('core', '0005_auto_20210423_0935'),
]

operations = [
migrations.RunPython(
title_case_named_coast_names,
reverse_code=migrations.RunPython.noop
),
]
28 changes: 28 additions & 0 deletions core/migrations/0007_auto_20210425_1732.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.1.7 on 2021-04-25 16:32

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0006_auto_20210423_1426'),
]

operations = [
migrations.AlterField(
model_name='game',
name='build_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], default='twelve_hours', max_length=100),
),
migrations.AlterField(
model_name='game',
name='order_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], default='twenty_four_hours', max_length=100, null=True),
),
migrations.AlterField(
model_name='game',
name='retreat_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], default='twenty_four_hours', max_length=100),
),
]
28 changes: 28 additions & 0 deletions core/migrations/0008_auto_20210426_1518.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.1.7 on 2021-04-26 14:18

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0007_auto_20210425_1732'),
]

operations = [
migrations.AlterField(
model_name='game',
name='build_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], max_length=100, null=True),
),
migrations.AlterField(
model_name='game',
name='order_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], max_length=100, null=True),
),
migrations.AlterField(
model_name='game',
name='retreat_deadline',
field=models.CharField(choices=[(None, 'None'), ('twelve_hours', '12 hours'), ('twenty_four_hours', '24 hours'), ('two_days', '2 days'), ('three_days', '3 days'), ('five_days', '5 days'), ('seven_days', '7 days')], max_length=100, null=True),
),
]
2 changes: 0 additions & 2 deletions core/migrations/fixtures/territory.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
31,
37,
51,
75,
75
],
"shared_coasts":[
Expand Down Expand Up @@ -762,7 +761,6 @@
],
"controlled_by_initial":3,
"nationality":3,
"nationality":3,
"type":"coastal"
}
},
Expand Down
2 changes: 2 additions & 0 deletions core/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ class NationChoiceMode:


class DeadlineFrequency:
NONE = None
TWELVE_HOURS = timespans.TWELVE_HOURS.db_string
TWENTY_FOUR_HOURS = timespans.TWENTY_FOUR_HOURS.db_string
TWO_DAYS = timespans.TWO_DAYS.db_string
THREE_DAYS = timespans.THREE_DAYS.db_string
FIVE_DAYS = timespans.FIVE_DAYS.db_string
SEVEN_DAYS = timespans.SEVEN_DAYS.db_string
CHOICES = (
(NONE, 'None'),
timespans.TWELVE_HOURS.as_choice,
timespans.TWENTY_FOUR_HOURS.as_choice,
timespans.TWO_DAYS.as_choice,
Expand Down
9 changes: 3 additions & 6 deletions core/models/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,18 @@ class Game(models.Model, AutoSlug):
max_length=100,
)
order_deadline = models.CharField(
null=False,
null=True,
choices=DeadlineFrequency.CHOICES,
default=DeadlineFrequency.TWENTY_FOUR_HOURS,
max_length=100,
)
retreat_deadline = models.CharField(
null=False,
null=True,
choices=DeadlineFrequency.CHOICES,
default=DeadlineFrequency.TWENTY_FOUR_HOURS,
max_length=100,
)
build_deadline = models.CharField(
null=False,
null=True,
choices=DeadlineFrequency.CHOICES,
default=DeadlineFrequency.TWELVE_HOURS,
max_length=100,
)
process_on_finalized_orders = models.BooleanField(
Expand Down
7 changes: 4 additions & 3 deletions core/models/turn.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ def new(self, **kwargs):
instance.
"""
turn = self.create(**kwargs)
td = timespan.get_timespan(turn.deadline).timedelta
turn_end_dt = timezone.now() + td
TurnEnd.objects.new(turn, turn_end_dt)
if turn.deadline:
td = timespan.get_timespan(turn.deadline).timedelta
turn_end_dt = timezone.now() + td
TurnEnd.objects.new(turn, turn_end_dt)
return turn


Expand Down
6 changes: 6 additions & 0 deletions core/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from core.models.base import DrawStatus, GameStatus
from core.models.mixins import AutoSlug
from core.utils.models import super_receiver
from project.celery import app


def set_id(instance):
Expand Down Expand Up @@ -72,6 +73,11 @@ def set_game_state_if_draw_accepted(sender, instance, **kwargs):
game.set_winners(*nations)


@receiver(signals.pre_delete, sender=models.TurnEnd)
def revoke_task_on_delete(sender, instance, **kwargs):
app.control.revoke(instance.task_id)


@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
"""
Expand Down
6 changes: 6 additions & 0 deletions core/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


apply_async_path = 'core.tasks.process_turn.apply_async'
revoke_task_on_delete_path = 'celery.app.control.Control.revoke'


set_status_path = 'core.models.Draw.set_status'
Expand Down Expand Up @@ -55,6 +56,11 @@ def patch_process_turn_apply_async(self):
self.apply_async = apply_async.start()
self.apply_async.return_value = AsyncResult(id=self.dummy_task_id)

def patch_revoke_task_on_delete(self):
self.revoke_task_on_delete_patcher = patch(revoke_task_on_delete_path)
self.revoke_task_on_delete_patch = self.revoke_task_on_delete_patcher.start()
self.addCleanup(self.revoke_task_on_delete_patcher.stop)

def patch_set_status(self):
self.set_status_patcher = patch(set_status_path)
self.set_status_patch = self.set_status_patcher.start()
Expand Down
Loading

0 comments on commit 32bcab6

Please sign in to comment.