-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBattleships_v0.2_core_2.6.3.ino
403 lines (317 loc) · 10.9 KB
/
Battleships_v0.2_core_2.6.3.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/******************************* BATTLESHIP ********************************
* Version 0.2b
* Author Gegeniger Anton
* Changes from v0.1
* - Render engine was redone, now insead of using one array for everything I have 4 arrays (arr_1 - main array for ships, arr_2 - show selected ship, arr_3 - collisions, arr_4 - final render
* - Collisions checking every Draw() cycle for each ship
* - Added WiFi connection (only connection, no data transfer yet)
* - Added animation before start (while WiFi connection establishing)
* - Added Game Mode variable
*
****************************************************************************/
#include "AiEsp32RotaryEncoder.h"
#include "Arduino.h"
#define FASTLED_INTERRUPT_RETRY_COUNT 0
#define FASTLED_ALLOW_INTERRUPTS 0
#define FASTLED_ESP8266_RAW_PIN_ORDER
#include <FastLED.h>
#include "classes.h"
#include <AceButton.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
// Set WiFi credentials
#define WIFI_SSID "******"
#define WIFI_PASS "**********"
#define UDP_PORT 4210
// UDP
WiFiUDP UDP;
char packet[255];
char reply_hit[] = "Hit!";
char reply_miss[] = "Miss!";
bool paired = false;
IPAddress ip(10, 0, 0, 111);
IPAddress gwIP(10, 0, 0, 1);
IPAddress msk(255, 255,255, 0);
IPAddress brdIP(10,0,0,255);
// GAME VARIABLES
bool readyToShoot = false;
bool OpponentReadyToShoot = false;
#define ROTARY_ENCODER_X_A_PIN 12
#define ROTARY_ENCODER_X_B_PIN 14
#define ROTARY_ENCODER_X_BUTTON_PIN 2
// Buttons configuration
#define LEFT_BUTTON_PIN D3
#define RIGHT_BUTTON_PIN D7
using namespace ace_button;
//
#define ROTARY_ENCODER_Y_A_PIN 4
#define ROTARY_ENCODER_Y_B_PIN 5
#define ROTARY_ENCODER_Y_BUTTON_PIN 2
#define ROTARY_ENCODER_X_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
#define ROTARY_ENCODER_Y_VCC_PIN -1
//depending on your encoder - try 1,2 or 4 to get expected behaviour
//#define ROTARY_ENCODER_X_STEPS 1
//#define ROTARY_ENCODER_X_STEPS 2
#define ROTARY_ENCODER_X_STEPS 4
#define ROTARY_ENCODER_Y_STEPS 4
#define LED_PIN D8
#define NUM_LEDS 100
AceButton leftButton(LEFT_BUTTON_PIN);
AceButton rightButton(RIGHT_BUTTON_PIN);
byte x,y;
byte old_x,old_y;
//bool set_arr[100];
byte game_mode = 0; //Game mode:
// 1 - Connection
// 2 - Ships allocation
// 3 - You shooting - Draw Aim and shots that were made
// 4 - Opponent shooting - Draw your ships and shots made by opponent
// 5 - Waiting for shoot/Receiving a shot
// 6 -
bool set;
byte sel_ship = 0; // sellected ship
bool chg_sel = false; //flag if selection was changed
byte arr_1[10][10];
byte arr_2[10][10]; // SELECTED SHIP
byte arr_3[10][10]; // COLLISION
byte arr_4[10][10]; //FINAL RENDER
byte arr_5[10][10]; //SHIP STORAGE
byte arr_6[10][10]; //SHOOTING FIELD
byte arr_7[10][10];
//byte ship_set[10][10];
byte ships_3[100] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
CRGB leds[NUM_LEDS];
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
//instead of changing here, rather change numbers above
//AiEsp32RotaryEncoder rotaryEncoderX = AiEsp32RotaryEncoder(ROTARY_ENCODER_X_A_PIN, ROTARY_ENCODER_X_B_PIN, ROTARY_ENCODER_X_VCC_PIN, ROTARY_ENCODER_X_STEPS);
AiEsp32RotaryEncoder rotaryEncoderX = AiEsp32RotaryEncoder(ROTARY_ENCODER_X_A_PIN, ROTARY_ENCODER_X_B_PIN, ROTARY_ENCODER_X_BUTTON_PIN, ROTARY_ENCODER_X_VCC_PIN, ROTARY_ENCODER_X_STEPS);
//AiEsp32RotaryEncoder rotaryEncoderY = AiEsp32RotaryEncoder(ROTARY_ENCODER_Y_A_PIN, ROTARY_ENCODER_Y_B_PIN, ROTARY_ENCODER_Y_VCC_PIN, ROTARY_ENCODER_Y_STEPS);
AiEsp32RotaryEncoder rotaryEncoderY = AiEsp32RotaryEncoder(ROTARY_ENCODER_Y_A_PIN, ROTARY_ENCODER_Y_B_PIN, ROTARY_ENCODER_Y_BUTTON_PIN, ROTARY_ENCODER_Y_VCC_PIN, ROTARY_ENCODER_Y_STEPS);
// Declaring SHIPS object array
SHIP ship1;
SHIP ships[5];
// ================== RIGHT BUTTON CLICK ===================
void right_Click()
{
switch (game_mode)
{
case 2: RotateShip();
break;
case 3: MakeShot(x,y);
}
}
//===========================================================
// ================== LEFT BUTTON CLICK ===================
void left_Click()
{
switch (game_mode)
{
case 2: SelectNextShip();
break;
}
}
//===========================================================
//========================= ENCODER EVENTS =============================
void rotary_loop()
{
switch (game_mode)
{
case 2: MoveShip();
break;
case 3: MoveAim();
break;
}
}
//===================================================================
// NEW EVENT HANDLER FOR BUTTONS
void handleEvent(AceButton* button, uint8_t eventType,
uint8_t /*buttonState*/) {
uint8_t pin = button->getPin();
if (pin == LEFT_BUTTON_PIN) {
switch (eventType) {
// Interpret a Released event as a Pressed event, to distiguish it
// from a LongPressed event.
case AceButton::kEventReleased:
Serial.print("LEFT BUTTON SHORT RELEASE");
left_Click();
break;
// LongPressed goes in and out of edit mode.
case AceButton::kEventLongReleased:
Serial.print("LEFT BUTTON LONG RELEASE");
break;
}
} else if (pin == RIGHT_BUTTON_PIN) {
switch (eventType) {
case AceButton::kEventReleased:
//Serial.print("RIGHT BUTTON SHORT RELEASE");
right_Click();
break;
// LongPressed goes in and out of edit mode.
case AceButton::kEventLongReleased:
//Serial.print("RIGHT BUTTON LONG RELEASE");
//isOverlap(&ships[sel_ship]);
SwitchGame();
break;
}
}
}
void IRAM_ATTR readEncoderISRX()
{
rotaryEncoderX.readEncoder_ISR();
}
void IRAM_ATTR readEncoderISRY()
{
rotaryEncoderY.readEncoder_ISR();
}
void setup()
{
Serial.begin(115200);
FastLED.addLeds<WS2812, 15, GRB>(leds, NUM_LEDS);
//we must initialize rotary encoder
rotaryEncoderX.begin();
rotaryEncoderX.setup(readEncoderISRX);
rotaryEncoderY.begin();
rotaryEncoderY.setup(readEncoderISRY);
// Button uses the built-in pull up register.
pinMode(LEFT_BUTTON_PIN, INPUT_PULLUP);
pinMode(RIGHT_BUTTON_PIN, INPUT_PULLUP);
// Configure the ButtonConfig with the event handler.
ButtonConfig* buttonConfig = ButtonConfig::getSystemButtonConfig();
buttonConfig->setEventHandler(handleEvent);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress);
x=0;
y=0;
bool circleValues = false;
rotaryEncoderX.setBoundaries(0, 9, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
rotaryEncoderY.setBoundaries(0, 9, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
rotaryEncoderX.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
rotaryEncoderY.disableAcceleration();
//rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
for (int i = 0; i<=9; i++)
{
for (int j = 0; j<=9; j++)
{
arr_1[j][i] = 0;
arr_2[j][i] = 0;
arr_3[j][i] = 0;
arr_4[j][i] = 0;
arr_5[j][i] = 0;
arr_6[j][i] = 0;
// ship_set[i][j] = 0;
}
}
game_mode = 1;
//ship1.create(0,0,5,1);
ships[0].create(0,0,5,0);
Serial.print(sizeof(ships));
ships[1].create(0,2,4,0);
Serial.print(sizeof(ships));
ships[2].create(0,4,3,0);
Serial.print(sizeof(ships));
ships[3].create(0,6,2,0);
Serial.print(sizeof(ships));
ships[4].create(0,8,2,0);
Serial.print(sizeof(ships));
//sel_ship=0;
ships[sel_ship].set = false;
}
//========================SET ENCODER ====================
void set_encoder(byte set_x, byte set_y) //RESET ENCODER WITH GIVEN X,Y
{
rotaryEncoderY.setEncoderValue(set_y);
rotaryEncoderX.setEncoderValue(set_x);
x=set_x;
y=set_y;
};
//=========================================================
//=====================================LOOP==============================================
void loop()
{
//WiFi.config(ip,gwIP,msk);
//WiFi.setSleepMode(WIFI_NONE_SLEEP);
bool opReady = false;
while (game_mode == 1)
{
// Begin WiFi
//WiFi.config(ip,gwIP,msk);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED)
{
confetti();
Serial.print(".");
}
Serial.println(WiFi.localIP());
// Begin listening to UDP port
UDP.begin(UDP_PORT);
Serial.print("Listening on UDP port ");
Serial.println(UDP_PORT);
while (!paired)
{
UDP.beginPacket(brdIP, UDP_PORT);
UDP.write("Connected");
UDP.endPacket();
int packetSize = UDP.parsePacket();
if (packetSize) {
int len = UDP.read(packet, 255);
if (len > 0)
{
packet[len] = '\0';
}
Serial.print("Packet received: ");
Serial.println(packet);
Serial.println("From: ");
Serial.print(UDP.remoteIP());
Serial.print(":");
Serial.print(UDP.remotePort());
String myString = String(packet);
if (myString == "Connected")
{
paired = true;
}
// Send return packet
UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
UDP.write("Connection Established");
UDP.endPacket();
}
delay(50);
confetti();
}
game_mode = 2;
}
while (game_mode == 2)
{
draw_ships();
rotary_loop();
leftButton.check();
rightButton.check();
delay(2);
opReady = isOpponentReady();
if (opReady) {
OpponentReadyToShoot = true;
}
}
while (game_mode == 3)
{
if (!opReady) {
opReady = isOpponentReady();
confetti();
} else {
rotary_loop();
leftButton.check();
rightButton.check();
draw_aim(x,y);
delay(2);
};
}
}