Browse Source

NIGHTMARE NIGHTMARE NIGHTMARE NIGHTMARE

Kirk Trombley 3 years ago
parent
commit
0b883011d1

+ 4 - 0
client/src/components/util/GameCreationForm/GameCreationForm.jsx

@@ -11,6 +11,7 @@ import {
   RANDOM_STREET_VIEW,
   TIME_BANK,
   URBAN,
+  NIGHTMARE,
 } from "../../../domain/constants";
 import useCountryLookup from "../../../hooks/useCountryLookup";
 import Loading from "../Loading";
@@ -263,6 +264,9 @@ const GameCreationForm = ({ afterCreate, lastSettings = null }) => {
             <Item value={HARD} display="😬">
               Hard Mode
             </Item>
+            <Item value={NIGHTMARE} display="💀">
+              Nightmare Mode
+            </Item>
           </Dropdown>
           <Dropdown
             selected={roundPointCap}

+ 1 - 0
client/src/domain/constants.js

@@ -18,3 +18,4 @@ export const RACE = "RACE";
 export const COUNTRY_RACE = "COUNTRYRACE";
 export const DISTANCE = "DISTANCE";
 export const HARD = "HARD";
+export const NIGHTMARE = "NIGHTMARE";

+ 12 - 7
server/app/api/game.py

@@ -147,13 +147,18 @@ async def submit_guess(round_number: conint(gt=0),
                  player: models.Player = Depends(get_player)):
     target = queries.get_coordinate(db, player.game_id, round_number)
     country_code = await reverse_geocode(guess.lat, guess.lng)
-    if game.score_method == ScoreMethodEnum.country_race:
-        score = scoring.score_country_race(target.country_code, country_code, guess.time_remaining, game.timer)
-        distance = None
-    elif game.score_method == ScoreMethodEnum.hard:
-        score, distance = scoring.score_hard((target.latitude, target.longitude), (guess.lat, guess.lng))
-    else:
-        score, distance = scoring.score((target.latitude, target.longitude), (guess.lat, guess.lng))
+    
+    match game.score_method:
+        case ScoreMethodEnum.country_race:
+            score = scoring.score_country_race(target.country_code, country_code, guess.time_remaining, game.timer)
+            distance = None
+        case ScoreMethodEnum.hard:
+            score, distance = scoring.score_hard((target.latitude, target.longitude), (guess.lat, guess.lng))
+        case ScoreMethodEnum.nightmare:
+            score, distance = scoring.score_nightmare((target.latitude, target.longitude), (guess.lat, guess.lng))
+        case _:
+            score, distance = scoring.score((target.latitude, target.longitude), (guess.lat, guess.lng))
+    
     if game.round_point_cap is not None:
         score = min(score, max(0, game.round_point_cap - sum(g.round_score for p in game.players for g in p.guesses if g.round_number == round_number)))
     added = queries.add_guess(db, guess, player, country_code, round_number, score)

+ 1 - 0
server/app/schemas.py

@@ -28,6 +28,7 @@ class ScoreMethodEnum(str, Enum):
     distance = "DISTANCE"
     country_race = "COUNTRYRACE"
     hard = "HARD"
+    nightmare = "NIGHTMARE"
 
 
 class GameConfig(CamelModel):

+ 31 - 7
server/app/scoring.py

@@ -11,18 +11,29 @@ max_dist_km = (math.pi * mean_earth_radius_km) / 2 # this is about 10,000 km
 # if you're within 1/16 of the Earth's circumfrence away, you get at least 1000 points
 quarter_of_max_km = max_dist_km / 4 # this is about 2,500 km
 
-# https://www.wolframalpha.com/input/?i=sqrt%28%28%28land+mass+of+earth%29+%2F+7%29%29+%2F+pi%29+in+kilometers
-# this is the average "radius" of a continent
+# this is the total of the land area of all continents on Earth except Antarctica
+relevant_land_area = sum([
+    3.036e7, # https://www.wolframalpha.com/input?i=geographic+area+of+africa+in+km2
+    4.981e7, # https://www.wolframalpha.com/input?i=geographic+area+of+asia+in+km2
+    2.450e7, # https://www.wolframalpha.com/input?i=geographic+area+of+north+america+in+km2
+    1.782e7, # https://www.wolframalpha.com/input?i=geographic+area+of+south+america+in+km2
+    5.973e6, # https://www.wolframalpha.com/input?i=geographic+area+of+europe+in+km2
+    8.563e6, # https://www.wolframalpha.com/input?i=geographic+area+of+oceania+in+km2
+])
+
+# this is the "radius" of an "average" continent
 # within this radius, you get at least 2000 points
-avg_continental_rad_km = 1468.0
+avg_continental_rad_km = math.sqrt(relevant_land_area / (6 * math.pi))
+# this works out to be approx 2700 km
 
 # somewhat arbitrarily, if you're within 1000 km, you get at least 3000 points
 one_thousand = 1000.0
 
-# https://www.wolframalpha.com/input?i=sqrt%28%28land+mass+of+earth%29+%2F+%28number+of+countries+on+earth%29%29+%2F+pi+in+kilometers
-# this is the average "radius" of a country
+# this is the "radius" of the "average" country
 # within this radius, you get at least 4000 points
-avg_country_rad_km = 270.7
+# TODO increment or decrement number of countries as wars develop
+avg_country_rad_km = math.sqrt(relevant_land_area / (206 * math.pi))
+# this works out to be approx 460 km
 
 # if you're within 150m, you get a perfect score of 5000
 min_dist_km = 0.15  
@@ -90,4 +101,17 @@ def score_hard(target: Tuple[float, float], guess: Tuple[float, float]) -> Tuple
     Returns (score, distance in km)
     """
     dist_km = haversine.haversine(target, guess)
-    return max(0, 5000 - int(dist_km * 1000)), dist_km
+    return max(0, 5000 - int(dist_km * 10)), dist_km
+
+
+def score_nightmare(target: Tuple[float, float], guess: Tuple[float, float]) -> Tuple[int, float]:
+    """
+    Takes in two (latitude, longitude) pairs and produces an int score.
+    Score is in the range (-inf, 5000]
+    Higher scores are closer.
+    Scoring is much, MUCH more punishing than standard
+
+    Returns (score, distance in km)
+    """
+    dist_km = haversine.haversine(target, guess)
+    return 5000 - int(dist_km * 1000), dist_km