awacke1 commited on
Commit
114d71b
·
verified ·
1 Parent(s): a62a6d0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +190 -0
app.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import folium
3
+ from streamlit_folium import folium_static
4
+ import time
5
+ import math
6
+ import random
7
+
8
+ # Wide mode
9
+ st.set_page_config(layout="wide")
10
+
11
+ # Deer hunting locations and resorts (approximated coordinates)
12
+ deer_hunting_spots = [
13
+ ("Buffalo County, WI", 44.3661, -91.7535, "Big Buck Capital", "Trophy bucks, rugged terrain"),
14
+ ("Winona County, MN", 44.0500, -91.6393, "Southeast MN", "Big bucks, public WMAs"),
15
+ ("Houston County, MN", 43.6666, -91.4929, "Southeast MN", "Thriving herds, farmland"),
16
+ ("Trempealeau County, WI", 44.3040, -91.3593, "Western WI", "Solid deer population"),
17
+ ("Crawford County, WI", 43.2396, -90.9315, "Western WI", "Driftless Area, deer paradise"),
18
+ ("Rutting Ridge Outfitters, WI", 44.4119, -91.8638, "Buffalo Co.", "Trophy hunts, rut focus"),
19
+ ("Deer Haven Acres, WI", 43.8769, -89.4825, "Adams Co.", "238-acre preserve"),
20
+ ("Nodak Lodge, MN", 47.5148, -94.8800, "Bena, MN", "Near Superior Nat’l Forest"),
21
+ ("Wigwam Resort, MN", 48.6029, -93.4037, "Baudette, MN", "Northern woods, big deer"),
22
+ ("Big River Resort, WI", 44.5896, -91.9988, "Alma, WI", "Chill vibes, near Rutting Ridge")
23
+ ]
24
+
25
+ # Initialize session state
26
+ if 'hunter_position' not in st.session_state:
27
+ st.session_state.hunter_position = [44.3661, -91.7535] # Start at Buffalo County
28
+ if 'is_traveling' not in st.session_state:
29
+ st.session_state.is_traveling = False
30
+ if 'start' not in st.session_state:
31
+ st.session_state.start = deer_hunting_spots[0]
32
+ if 'destination' not in st.session_state:
33
+ st.session_state.destination = deer_hunting_spots[1]
34
+ if 'start_time' not in st.session_state:
35
+ st.session_state.start_time = None
36
+ if 'elapsed_time' not in st.session_state:
37
+ st.session_state.elapsed_time = 0
38
+ if 'arrived' not in st.session_state:
39
+ st.session_state.arrived = False
40
+ if 'score' not in st.session_state:
41
+ st.session_state.score = 0
42
+ if 'deer_remaining' not in st.session_state:
43
+ st.session_state.deer_remaining = 0
44
+
45
+ # Distance calculation (Haversine in miles)
46
+ def calculate_distance(lat1, lon1, lat2, lon2):
47
+ R = 3958.8
48
+ lat1_rad, lon1_rad = math.radians(lat1), math.radians(lon1)
49
+ lat2_rad, lon2_rad = math.radians(lat2), math.radians(lon2)
50
+ dlat = lat2_rad - lat1_rad
51
+ dlon = lon2_rad - lon1_rad
52
+ a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**2
53
+ c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
54
+ return R * c
55
+
56
+ # Create map
57
+ def create_map():
58
+ m = folium.Map(location=st.session_state.hunter_position, zoom_start=8, tiles="CartoDB Positron")
59
+ for spot in deer_hunting_spots:
60
+ folium.Marker(
61
+ location=[spot[1], spot[2]],
62
+ popup=f'<b>{spot[0]}</b><br>{spot[3]}<br>{spot[4]}',
63
+ icon=folium.Icon(color='green', icon='tree', prefix='fa')
64
+ ).add_to(m)
65
+ folium.Marker(
66
+ location=st.session_state.hunter_position,
67
+ popup='Hunter’s Rig',
68
+ icon=folium.Icon(color='blue', icon='truck', prefix='fa')
69
+ ).add_to(m)
70
+ return m
71
+
72
+ # Move hunter's rig
73
+ def move_rig(total_distance, step_time):
74
+ target = [st.session_state.destination[1], st.session_state.destination[2]]
75
+ current = st.session_state.hunter_position
76
+ remaining_distance = calculate_distance(current[0], current[1], target[0], target[1])
77
+ speed = total_distance / 25.0 # miles per second (25s total travel)
78
+ step_distance = speed * step_time
79
+ total_lat_diff = target[0] - current[0]
80
+ total_lon_diff = target[1] - current[1]
81
+ total_hyp = math.sqrt(total_lat_diff**2 + total_lon_diff**2)
82
+ if total_hyp > 0:
83
+ lat_step = (total_lat_diff / total_hyp) * step_distance / (calculate_distance(current[0], current[1], current[0] + 0.01, current[1]) / 0.01)
84
+ lon_step = (total_lon_diff / total_hyp) * step_distance / (calculate_distance(current[0], current[1], current[0], current[1] + 0.01) / 0.01)
85
+ st.session_state.hunter_position[0] += lat_step
86
+ st.session_state.hunter_position[1] += lon_step
87
+ if remaining_distance < 0.1:
88
+ st.session_state.hunter_position = target
89
+ st.session_state.is_traveling = False
90
+ st.session_state.arrived = True
91
+
92
+ # Simple 3D hunting simulation (text-based for Streamlit)
93
+ def hunt_deer(location):
94
+ if st.session_state.deer_remaining == 0:
95
+ st.session_state.deer_remaining = random.randint(3, 6) # Deer at location
96
+ st.write(f"Hunting at {location[0]}: {st.session_state.deer_remaining} deer spotted.")
97
+ action = st.radio("Choose your action:", ("Aim and Shoot", "Wait", "Move"))
98
+ if action == "Aim and Shoot":
99
+ if random.random() < 0.7: # 70% success rate
100
+ st.session_state.score += 50
101
+ st.session_state.deer_remaining -= 1
102
+ st.success("🎯 Deer hunted! +50 points")
103
+ else:
104
+ st.warning("Missed the shot!")
105
+ elif action == "Wait":
106
+ st.write("You wait quietly... deer are still around.")
107
+ elif action == "Move":
108
+ st.session_state.deer_remaining -= random.randint(0, 2) # Some deer might flee
109
+ st.write("You move, startling some deer.")
110
+ if st.session_state.deer_remaining <= 0:
111
+ st.write("No more deer in this area. Travel to another spot!")
112
+ st.write(f"Score: {st.session_state.score}")
113
+
114
+ # Layout
115
+ left_col, right_col = st.columns([3, 1])
116
+
117
+ # Left column: Map and controls
118
+ with left_col:
119
+ st.markdown("### 🦌 Deer Hunter’s Basecamp 🌲")
120
+ m = create_map()
121
+ folium_static(m, width=960, height=540)
122
+
123
+ col1, col2, col3 = st.columns(3)
124
+ with col1:
125
+ if st.button("🚚 Launch Rig"):
126
+ st.session_state.is_traveling = True
127
+ st.session_state.start_time = time.time()
128
+ st.session_state.arrived = False
129
+ with col2:
130
+ if st.button("🛑 Stop Rig"):
131
+ st.session_state.is_traveling = False
132
+ st.session_state.start_time = None
133
+ with col3:
134
+ if st.button("🔄 Reset to Start"):
135
+ st.session_state.hunter_position = [st.session_state.start[1], st.session_state.start[2]]
136
+ st.session_state.is_traveling = False
137
+ st.session_state.start_time = None
138
+ st.session_state.elapsed_time = 0
139
+ st.session_state.arrived = False
140
+ st.session_state.deer_remaining = 0
141
+ st.rerun()
142
+
143
+ if st.session_state.arrived:
144
+ st.success(f"🎯 Arrived at {st.session_state.destination[0]}!")
145
+ hunt_deer(st.session_state.destination)
146
+
147
+ # Right column: Stats and navigation
148
+ with right_col:
149
+ st.markdown("### 📡 Hunt Status")
150
+ total_distance = calculate_distance(st.session_state.start[1], st.session_state.start[2],
151
+ st.session_state.destination[1], st.session_state.destination[2])
152
+ remaining_distance = calculate_distance(st.session_state.hunter_position[0], st.session_state.hunter_position[1],
153
+ st.session_state.destination[1], st.session_state.destination[2])
154
+ speed = total_distance / (25.0 / 3600) # mph
155
+ st.write(f"**Start**: {st.session_state.start[0]}")
156
+ st.write(f"**Destination**: {st.session_state.destination[0]}")
157
+ st.write(f"**Total Distance**: {total_distance:.1f} miles")
158
+ st.write(f"**Remaining**: {remaining_distance:.1f} miles")
159
+ st.write(f"**Speed**: {speed:.1f} mph")
160
+ st.write(f"**ETA**: 25.0 seconds")
161
+ st.write(f"**Score**: {st.session_state.score}")
162
+
163
+ start_col, dest_col = st.columns(2)
164
+ with start_col:
165
+ st.write("**🚦 Start Points**")
166
+ for spot in deer_hunting_spots:
167
+ if st.button(f"📍 {spot[0]}", key=f"start_{spot[0]}"):
168
+ st.session_state.start = spot
169
+ st.session_state.hunter_position = [spot[1], spot[2]]
170
+ st.session_state.is_traveling = False
171
+ st.session_state.arrived = False
172
+ st.session_state.deer_remaining = 0
173
+ st.rerun()
174
+ with dest_col:
175
+ st.write("**🏁 Destinations**")
176
+ for spot in deer_hunting_spots:
177
+ if st.button(f"🎯 {spot[0]}", key=f"dest_{spot[0]}"):
178
+ st.session_state.destination = spot
179
+ st.session_state.is_traveling = False
180
+ st.session_state.arrived = False
181
+ st.session_state.deer_remaining = 0
182
+ st.rerun()
183
+
184
+ # Movement logic
185
+ if st.session_state.is_traveling:
186
+ move_rig(total_distance, 0.5)
187
+ if st.session_state.start_time:
188
+ st.session_state.elapsed_time = time.time() - st.session_state.start_time
189
+ time.sleep(0.5)
190
+ st.rerun()