Here is the full code:
#include <WiFi.h>
#include <WebServer.h>
#include <FastLED.h>
#include <sstream>
#include <ArduinoJson.h>
#include <Preferences.h>
#include "index.h"
#include "shoot.h"
#include "highscores.h"
//using std::literals::string_literals;
// Replace with your network credentials
const char* ssid = "***********";
const char* password = "********";
WebServer server(80);
char htmlShootFull[50000];
bool startshooting = false; //prepare system
bool shooting = false; //active shooting
enum eProgStep {STARTUPTIMER, INCREASESHOT, WAITREACTION, SELECTTARGET, SETLEDS, WAITFORSHOT, CALCSCORE, WAIT, SAVEHIGHSCORE, END, SHOWGOOD, SHOWBAD};
eProgStep progStep = WAIT;
int targets[5]; //0 = not a target. 1 = target. 2 = swinging
unsigned long swingTargets[5];
int currMag = 0;
int currBull = 0;
int currMs = 0;
bool forceLeds = false;
unsigned long blinkswitch;
unsigned long startWaitReaction;
int reactionTime;
bool isOrange = false;
int micPin = 25;
int target1Pin = 32;
int target2Pin = 33;
int target3Pin = 34;
int target4Pin = 35;
int micVal;
int target1Val;
int target2Val;
int target3Val;
int target4Val;
#define LEDS_PER_TARGET 2
#define NUM_LEDS 8 //4*ledsPerTarget
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
#define DATA_PIN 22
CRGB leds[NUM_LEDS];
unsigned long startUpTime;
unsigned long startTime;
unsigned long startMagChange;
unsigned long lastLedWrite;
unsigned long startShowResultWrite;
String highscoreNames[10];
double highscoreScores[10];
double timeMag1[18];
double timeMag2[18];
double timeMag3[18];
double timeMag4[18];
double timeMag5[18];
double scoreMag1[18];
double scoreMag2[18];
double scoreMag3[18];
double scoreMag4[18];
double scoreMag5[18];
double totalTimeMag1;
double totalTimeMag2;
double totalTimeMag3;
double totalTimeMag4;
double totalTimeMag5;
double avgTimeMag1;
double avgTimeMag2;
double avgTimeMag3;
double avgTimeMag4;
double avgTimeMag5;
double totalScoreMag1;
double totalScoreMag2;
double totalScoreMag3;
double totalScoreMag4;
double totalScoreMag5;
double avgScoreMag1;
double avgScoreMag2;
double avgScoreMag3;
double avgScoreMag4;
double avgScoreMag5;
double totalTime;
double avgTime;
double totalScore;
double avgScore;
double rankingAvgScore;
double startdelay = 5;
double shoottimeout = 3;
int magchangetime = 3;
int magchangemin1 = 0;
int ntargets = 1;
int badtargets = 0;
int reactmode = 0;
int holster = 0;
int nmag = 3;
int nbull = 10;
String shooter = "";
double distance = 10;
Preferences preferences;
void setup(void) {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
pinMode(micPin, INPUT);
pinMode(target1Pin, INPUT);
pinMode(target2Pin, INPUT);
pinMode(target3Pin, INPUT);
pinMode(target4Pin, INPUT);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/highscores", handleHighscores);
server.on("/gethighscores", handleGetHighscores);
server.on("/shoot", handleShoot);
server.on("/getvals", handleGetVals);
server.begin();
Serial.println("HTTP server started");
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
progStep = END;
preferences.begin("highscores", false);
//String highscoreNames[10];
//double highscoreScores[10];
/* for (int i = 0; i < 10; i++)
{
highscoreNames[i] = preferences.getString("name" + i, "nothing");
highscoreScores[i] = preferences.getDouble("score" + i, -10);
Serial.println(highscoreScores[i]);
}*/
highscoreNames[0] = preferences.getString("name0", "--");
highscoreScores[0] = preferences.getDouble("score0", 0);
highscoreNames[1] = preferences.getString("name1", "--");
highscoreScores[1] = preferences.getDouble("score1", 0);
highscoreNames[2] = preferences.getString("name2", "--");
highscoreScores[2] = preferences.getDouble("score2", 0);
highscoreNames[3] = preferences.getString("name3", "--");
highscoreScores[3] = preferences.getDouble("score3", 0);
highscoreNames[4] = preferences.getString("name4", "--");
highscoreScores[4] = preferences.getDouble("score4", 0);
highscoreNames[5] = preferences.getString("name5", "--");
highscoreScores[5] = preferences.getDouble("score5", 0);
highscoreNames[6] = preferences.getString("name6", "--");
highscoreScores[6] = preferences.getDouble("score6", 0);
highscoreNames[7] = preferences.getString("name7", "--");
highscoreScores[7] = preferences.getDouble("score7", 0);
highscoreNames[8] = preferences.getString("name8", "--");
highscoreScores[8] = preferences.getDouble("score8", 0);
highscoreNames[9] = preferences.getString("name9", "--");
highscoreScores[9] = preferences.getDouble("score9", 0);
preferences.end();
}
void loop(void) {
server.handleClient();
//check for swinging targets
for (int i = 1; i <= 4; i++)
{
if ((millis() - swingTargets[i] > 500) and (targets[i] == 2))
{
targets[i] = 0;
}
}
handleLeds();
if (startshooting)
{
targets[1] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[2] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[3] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[4] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
currMag = 1;
currBull = 0;
currMs = 0;
startshooting = false;
shooting = true;
totalTimeMag1 = 0;
totalScoreMag1 = 0;
avgTimeMag1 = 0;
avgScoreMag1 = 0;
totalTimeMag2 = 0;
totalScoreMag2 = 0;
avgTimeMag2 = 0;
avgScoreMag2 = 0;
totalTimeMag3 = 0;
totalScoreMag3 = 0;
avgTimeMag3 = 0;
avgScoreMag3 = 0;
totalTimeMag4 = 0;
totalScoreMag4 = 0;
avgTimeMag4 = 0;
avgScoreMag4 = 0;
totalTimeMag5 = 0;
totalScoreMag5 = 0;
avgTimeMag5 = 0;
avgScoreMag5 = 0;
totalTime = 0;
totalScore = 0;
avgTime = 0;
avgScore = 0;
startUpTime = millis();
progStep = STARTUPTIMER;
}
//enum progStep {STARTUPTIMER, INCREASESHOT, WAITREACTION, SELECTTARGET, WAITFORSHOT, CALCSCORE, WAIT, END};
if (shooting)
{
if (progStep == STARTUPTIMER)
{
unsigned long now = millis();
if (now - startUpTime > 1000 * startdelay)
{
progStep = INCREASESHOT;
}
}
if (progStep == INCREASESHOT)
{
//increase the current shot:
currBull = currBull + 1;
if (reactmode == 0)
{
progStep = SELECTTARGET;
}
else
{
startWaitReaction = millis();
reactionTime = random(500, 5000);
progStep = WAITREACTION;
}
if ((currBull == nbull) and (magchangemin1 == 1) and (currMag < nmag))
{
startMagChange = millis();
Serial.println("WAIT"); progStep = WAIT;
}
if (currBull > nbull)
{
currMag = currMag + 1;
currBull = 1;
startMagChange = millis();
if (magchangemin1 == 0)
{
progStep = WAIT;
}
else
{
if (reactmode == 0)
{
progStep = SELECTTARGET;
}
else
{
startWaitReaction = millis();
reactionTime = random(500, 5000);
progStep = WAITREACTION;
}
}
}
if (currMag > nmag)
{
progStep = SAVEHIGHSCORE;
}
}
if (progStep == WAITREACTION)
{
unsigned long now = millis();
if (now - startWaitReaction > reactionTime)
{
progStep = SELECTTARGET;
}
}
if (progStep == SELECTTARGET)
{
bool foundTarget = false;
while ( not foundTarget)
{
//int targets[5]; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
int iTarget;
iTarget = random(1, 5);
if (targets[iTarget] == 0)
{
targets[iTarget] = 1;
foundTarget = true;
//if needed search for a bad target.
if (badtargets == 1)
{
bool foundBADTarget = false;
while ( not foundBADTarget)
{
int iTarget;
iTarget = random(1, 5);
if (targets[iTarget] == 0)
{
targets[iTarget] = 3;
foundBADTarget = true;
}
}
}
progStep = WAITFORSHOT;
forceLeds = true;
startTime = millis();
}
}
}
if (progStep == WAIT)
{
unsigned long now = millis();
if (now - startMagChange > 1000 * magchangetime)
{
if (reactmode == 0)
{
progStep = SELECTTARGET;
}
else
{
startWaitReaction = millis();
reactionTime = random(500, 5000);
progStep = WAITREACTION;
}
}
}
if (progStep == WAITFORSHOT)
{
micVal = digitalRead(micPin);
target1Val = digitalRead(target1Pin);
target2Val = digitalRead(target2Pin);
target3Val = digitalRead(target3Pin);
target4Val = digitalRead(target4Pin);
int iHitTarget = 0;
if (target1Val == 1)
{
iHitTarget = 1;
}
if (target2Val == 1)
{
iHitTarget = 2;
}
if (target3Val == 1)
{
iHitTarget = 3;
}
if (target4Val == 1)
{
iHitTarget = 4;
}
if ((targets[1] == 1 and target1Val == 1) or (targets[2] == 1 and target2Val == 1) or (targets[3] == 1 and target3Val == 1) or (targets[4] == 1 and target4Val == 1))
{
/*
double startdelay = 5;
double shoottimeout = 3;
int magchangetime = 3;
int magchangemin1 = 0;
int ntargets = 1;
int badtargets = 0;
int reactmode = 0;
int holster = 0;
int nmag = 3;
int nbull = 10;
String shooter = "";
double distance = 10;*/
//Correct target hit
currMs = millis() - startTime;
double score;
//base score
if ((holster == 1) and (currMag == 1) and (currBull == 1))
{
score = (1.0 / (double)(currMs - 700)) * 1000;
}
else
{
score = (1.0 / (double)currMs) * 1000;
}
//correct for distance
double distFactor = atan2(0.1, distance) * 50;
score = score / distFactor;
//correct for shot timeout
score = score - shoottimeout / 20;
//correct for enabled bad targets
score = score + score * badtargets * 0.1;
targets[1] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[2] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[3] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[4] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[iHitTarget] = 2;
swingTargets[iHitTarget] = millis();
if (currMag == 1)
{
scoreMag1[currBull] = score;
timeMag1[currBull] = currMs;
}
if (currMag == 2)
{
scoreMag2[currBull] = score;
timeMag2[currBull] = currMs;
}
if (currMag == 3)
{
scoreMag3[currBull] = score;
timeMag3[currBull] = currMs;
}
if (currMag == 4)
{
scoreMag4[currBull] = score;
timeMag4[currBull] = currMs;
}
if (currMag == 5)
{
scoreMag5[currBull] = score;
timeMag5[currBull] = currMs;
}
startShowResultWrite = millis();
progStep = SHOWGOOD;
}
else if ((targets[1] == 1 and (target2Val == 1 or target3Val == 1 or target4Val == 1))
or (targets[2] == 1 and (target1Val == 1 or target3Val == 1 or target4Val == 1))
or (targets[3] == 1 and (target1Val == 1 or target2Val == 1 or target4Val == 1))
or (targets[4] == 1 and (target1Val == 1 or target2Val == 1 or target3Val == 1))
or (micVal == 1)
or (millis() - startTime >= shoottimeout * 1000))
{
targets[1] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[2] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[3] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[4] = 0; //0 = not a target. 1 = target. 2 = swinging. 3 = good guy. 4 = wait state.
targets[iHitTarget] = 2;
swingTargets[iHitTarget] = millis();
currMs = millis() - startTime;
if (currMs > shoottimeout * 1000)
{
currMs = shoottimeout * 1000;
}
double score = -5 - shoottimeout / 20;
//hit wrong plate or missed
if (currMag == 1)
{
scoreMag1[currBull] = score;
timeMag1[currBull] = currMs;
}
if (currMag == 2)
{
scoreMag2[currBull] = score;
timeMag2[currBull] = currMs;
}
if (currMag == 3)
{
scoreMag3[currBull] = score;
timeMag3[currBull] = currMs;
}
if (currMag == 4)
{
scoreMag4[currBull] = score;
timeMag4[currBull] = currMs;
}
if (currMag == 5)
{
scoreMag5[currBull] = score;
timeMag5[currBull] = currMs;
}
startShowResultWrite = millis();
progStep = SHOWBAD;
}
}
if (progStep == SAVEHIGHSCORE)
{
//check if the highscore needs to be saved.
bool highscoreChanged = false;
int rankinglocation = 10;
for (int i = 9; i >= 0; i--)
{
//find index where we have to insert the score
if (highscoreScores[i] < rankingAvgScore)
{
rankinglocation = i;
}
}
if (rankinglocation < 9)
{
for (int i = 8; i >= rankinglocation; i--)
{
Serial.println("write 1");
highscoreNames[i] = highscoreNames[i - 1];
highscoreScores[i] = highscoreScores[i - 1];
}
}
if (rankinglocation < 10)
{
highscoreNames[rankinglocation] = shooter;
highscoreScores[rankinglocation] = rankingAvgScore;
highscoreChanged = true;
Serial.println("save value");
Serial.println(rankinglocation);
Serial.println(highscoreNames[rankinglocation]);
}
if (highscoreChanged == true)
{
Serial.println("highscore changed");
Serial.println(highscoreScores[0]);
preferences.begin("highscores", false);
/* for (int i = 0; i < 10; i++)
{
preferences.putString("name" + i, highscoreNames[i]);
preferences.putDouble("score" + i, highscoreScores[i]);
}*/
preferences.putString("name0", highscoreNames[0]);
preferences.putDouble("score0", highscoreScores[0]);
preferences.putString("name1", highscoreNames[1]);
preferences.putDouble("score1", highscoreScores[1]);
preferences.putString("name2", highscoreNames[2]);
preferences.putDouble("score2", highscoreScores[2]);
preferences.putString("name3", highscoreNames[3]);
preferences.putDouble("score3", highscoreScores[3]);
preferences.putString("name4", highscoreNames[4]);
preferences.putDouble("score4", highscoreScores[4]);
preferences.putString("name5", highscoreNames[5]);
preferences.putDouble("score5", highscoreScores[5]);
preferences.putString("name6", highscoreNames[6]);
preferences.putDouble("score6", highscoreScores[6]);
preferences.putString("name7", highscoreNames[7]);
preferences.putDouble("score7", highscoreScores[7]);
preferences.putString("name8", highscoreNames[8]);
preferences.putDouble("score8", highscoreScores[8]);
preferences.putString("name9", highscoreNames[9]);
preferences.putDouble("score9", highscoreScores[9]);
preferences.end();
}
progStep = END;
}
if (progStep == SHOWGOOD)
{
if (millis() - startShowResultWrite >= 200)
{
progStep = INCREASESHOT;
}
}
if (progStep == SHOWBAD)
{
if (millis() - startShowResultWrite >= 200)
{
progStep = INCREASESHOT;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
.......
}