26 portal1Loc = portal2Loc = -1;
28 std::fill_n(&world[0], 512,
kEmpty);
29 for (
int x = 0; x <
width; x++)
34 void SnakeBird::Reset()
38 portal1Loc = portal2Loc = -1;
40 std::fill_n(&world[0], 512,
kEmpty);
41 for (
int x = 0; x <
width; x++)
45 for (
int x = 0; x < objects.size(); x++)
49 void SnakeBird::BiggerMapHeight()
53 std::array<SnakeBirdWorldObject, 512> worldCopy;
58 for (
int snake = 0; startState.GetNumSnakes()-1 >= snake; snake++)
60 int snakeHead = startState.GetSnakeHeadLoc(snake);
61 std::vector<snakeDir> snakeBody;
62 for (
int t = 0; t <= startState.GetSnakeLength(snake)-2; t++)
64 snakeBody.push_back(startState.GetSnakeDir(snake, t));
67 for (
int i = 0; i <=
height+1; i++)
71 startState.SetSnakeHeadLoc(snake, snakeHead+i+1);
72 startState.SetSnakeLength(snake, 1);
76 if (snakeBody.size() >= 1)
78 startState.SetSnakeLength(snake, snakeBody.size()+1);
79 for (
int x = 0; x < snakeBody.size(); x++)
80 startState.SetSnakeDir(snake, x, snakeBody[x]);
89 for (
int x = 0; x <= worldCopy.size()-1; x++)
91 if (worldCopy[x] !=
kEmpty)
93 for (
int i = 0; i <=
height; i++)
99 world[x+i+1] = worldCopy[x];
104 world[x+i+1] = worldCopy[x];
112 if (portal1Loc != -1)
114 for (
int i = 0; i <=
height; i++)
116 if (portal1Loc/(
height-1) >= i && portal1Loc/(
height-1) < i+1)
118 portal1Loc = portal1Loc+i+1;
124 if (portal2Loc != -1)
126 for (
int i = 0; i <=
height; i++)
128 if (portal2Loc/(
height-1) >= i && portal2Loc/(
height-1) < i+1)
130 portal2Loc = portal2Loc+i+1;
138 for (
int i = 1; i <=
width; i++)
140 if (exitLoc/(
height-1) >= i && exitLoc/(
height-1) < i+1)
142 exitLoc = exitLoc+i+1;
147 if (fruit.size() >= 1)
149 for (
int x = 0; x <= fruit.size()-1; x++)
151 for (
int i = 1; i <=
height; i++)
153 if (fruit[x]/(
height-1) >= i && fruit[x]/(
height-1) < i+1)
155 fruit[x] = fruit[x]+i+1;
162 for (
int which = 0; which <= 3; which++)
164 if (objects[which].size() >= 1)
166 for (
int vector = 0; vector <= objects[which].size()-1; vector++)
168 for (
int i = 1; i <=
height; i++)
170 if (objects[which][vector]/(
height-1) >= i && objects[which][vector]/(
height-1) < i+1)
172 objects[which][vector] = objects[which][vector]+i+1;
207 void SnakeBird::BiggerMapWidth()
214 void SnakeBird::SmallerMapHeight()
218 std::array<SnakeBirdWorldObject, 512> worldCopy;
227 for (
int snake = 0; startState.GetNumSnakes()-1 >= snake; snake++)
229 int snakeHead = startState.GetSnakeHeadLoc(snake);
230 int endofSnakeX =
GetX(snakeHead);
231 int endofSnakeY =
GetY(snakeHead);
232 std::vector<snakeDir> snakeBody;
233 std::vector<int> snakeBodyCoordinates;
234 for (
int t = 0; t <= startState.GetSnakeLength(snake)-2; t++)
236 if (startState.GetSnakeDir(snake, t) ==
kRight)
240 else if (startState.GetSnakeDir(snake, t) ==
kLeft)
244 else if (startState.GetSnakeDir(snake, t) ==
kDown)
248 else if (startState.GetSnakeDir(snake, t) ==
kUp)
252 snakeBody.push_back(startState.GetSnakeDir(snake, t));
254 if (startState.GetSnakeHeadLoc(snake)%
height == 0)
256 for (
int i = 0; i <=
height-1; i++)
258 if ((snakeHead-1)/(
height) >= i && (snakeHead-1)/(
height) < i+1)
260 startState.SetSnakeHeadLoc(snake, snakeHead-i-2);
261 startState.SetSnakeLength(snake, snakeBody.size()+1);
262 if (snakeBody.size() >= 1)
264 for (
int x = 0; x < snakeBody.size(); x++)
265 startState.SetSnakeDir(snake, x, snakeBody[x]);
272 for (
int i = 0; i <=
height-1; i++)
274 if ((snakeHead-1)/(
height) >= i && (snakeHead-1)/(
height) < i+1)
276 startState.SetSnakeHeadLoc(snake, snakeHead-i-1);
277 startState.SetSnakeLength(snake, 1);
281 if (snakeBody.size() >= 1)
283 startState.SetSnakeLength(snake, snakeBody.size()+1);
284 for (
int x = 0; x < snakeBody.size(); x++)
285 startState.SetSnakeDir(snake, x, snakeBody[x]);
292 for (
int x = 0; x <= worldCopy.size()-1; x++)
294 if (worldCopy[x] !=
kEmpty)
296 for (
int i = 0; i <=
width; i++)
302 world[x-i-1-15] = worldCopy[x];
307 world[x-i-1] = worldCopy[x];
315 if (portal1Loc != -1)
317 for (
int i = 0; i <=
height; i++)
319 if (portal1Loc%(
height+1) == 0)
324 if ((portal1Loc-1)/(
height+1) >= i && (portal1Loc-1)/(
height+1) < i+1)
326 portal1Loc = portal1Loc-i-1;
332 if (portal2Loc != -1)
334 for (
int i = 0; i <=
height; i++)
336 if (portal2Loc%(
height+1) == 0)
341 if ((portal2Loc-1)/(
height+1) >= i && (portal2Loc-1)/(
height+1) < i+1)
343 portal2Loc = portal2Loc-i-1;
351 for (
int i = 1; i <=
width; i++)
353 if (exitLoc%(
height+1) == 0)
358 if ((exitLoc-1)/(
height+1) >= i && (exitLoc-1)/(
height+1) < i+1)
360 exitLoc = exitLoc-i-1;
366 if (fruit.size() >= 1)
368 for (
int x = 0; x <= fruit.size()-1; x++)
370 for (
int i = 1; i <=
height; i++)
372 if (fruit[x]%(
height+1) == 0)
374 std::vector<int>::iterator tor = std::find(fruit.begin(), fruit.end(), GetIndex(x, 0));
375 if (tor != fruit.end())
381 if ((fruit[x]-1)/(
height+1) >= i && (fruit[x]-1)/(
height+1) < i+1)
383 fruit[x] = fruit[x]-i-1;
390 for (
int which = 0; which <= 3; which++)
392 if (objects[which].size() >= 1)
394 for (
int vector = 0; vector <= objects[which].size()-1; vector++)
396 for (
int i = 1; i <=
height; i++)
398 if ((objects[which][vector]+1)/(
height+1) >= i && (objects[which][vector]-1)/(
height+1) < i+1 && objects[which][vector]%(
height+1) != 0)
400 objects[which][vector] = objects[which][vector]-i-1;
411 void SnakeBird::SmallerMapWidth()
417 for (
int snake = 0; startState.GetNumSnakes()-1 >= snake; snake++)
419 int snakeHead = startState.GetSnakeHeadLoc(snake);
420 int endofSnakeX =
GetX(snakeHead);
421 int endofSnakeY =
GetY(snakeHead);
422 std::vector<snakeDir> snakeBody;
423 for (
int t = 0; t <= startState.GetSnakeLength(snake)-2; t++)
425 if (startState.GetSnakeDir(snake, t) ==
kRight)
429 else if (startState.GetSnakeDir(snake, t) ==
kLeft)
433 else if (startState.GetSnakeDir(snake, t) ==
kDown)
437 else if (startState.GetSnakeDir(snake, t) ==
kUp)
442 if (endofSnakeX ==
width-1)
444 startState.SetSnakeLength(snake, t);
447 snakeBody.push_back(startState.GetSnakeDir(snake, t));
449 if (
GetX(startState.GetSnakeHeadLoc(snake)) ==
width-1)
451 startState.SetSnakeHeadLoc(snake, GetIndex(
GetX(snakeHead)-1,
GetY(snakeHead)));
452 startState.SetSnakeLength(snake, snakeBody.size()+1);
453 if (snakeBody.size() >= 1)
455 for (
int x = 0; x < snakeBody.size(); x++)
456 startState.SetSnakeDir(snake, x, snakeBody[x]);
468 void SnakeBird::BeginEditing()
476 void SnakeBird::EndEditing()
479 for (
int x = 0; x < 4; x++)
481 bool connected =
false;
483 for (
int u = 0; u < objects[x].size(); u++)
485 for (
int v = 0; v < objects[x].size(); v++)
487 if (Distance(objects[x][u], objects[x][v]) == 1)
491 objectFullyConnected[x] = connected;
519 void SnakeBird::AddSnake(
int x,
int y,
const std::vector<snakeDir> &body)
522 startState.SetNumSnakes(count+1);
523 startState.SetSnakeHeadLoc(count, GetIndex(x, y));
524 startState.SetSnakeLength(count, body.size()+1);
525 for (
int x = 0; x < body.size(); x++)
526 startState.SetSnakeDir(count, x, body[x]);
529 void SnakeBird::AddSnakeHead(
int x,
int y,
int whichSnake)
531 if (GetIndex(x, y) >= 0 && GetIndex(x, y) <
width*
height && y <=
height-2 && x <=
width-1 && GetIndex(x, y) != startState.GetSnakeHeadLoc(whichSnake))
533 if (startState.GetNumSnakes() == whichSnake)
534 startState.SetNumSnakes(whichSnake+1);
535 startState.SetSnakeHeadLoc(whichSnake, GetIndex(x, y));
536 startState.SetSnakeLength(whichSnake, 1);
540 snakeDir SnakeBird::GetAddingDirection(
int x,
int y,
int endX,
int endY)
542 if ((x-1 == endX) && (y == endY))
546 else if ((x+1 == endX) && (y == endY))
550 else if ((y-1 == endY) && (x == endX))
554 else if ((y+1 == endY) && (x == endX))
561 void SnakeBird::AddSnakeBody(
int x,
int y,
int whichSnake)
565 int endofSnakeX =
GetX(startState.GetSnakeHeadLoc(whichSnake));
566 int endofSnakeY =
GetY(startState.GetSnakeHeadLoc(whichSnake));
567 if (startState.GetSnakeLength(whichSnake) >= 2 && startState.GetSnakeLength(whichSnake) <= 30)
569 for (
int t = 0; t <= startState.GetSnakeLength(whichSnake)-2; t++)
571 if (startState.GetSnakeDir(whichSnake, t) ==
kRight)
575 else if (startState.GetSnakeDir(whichSnake, t) ==
kLeft)
579 else if (startState.GetSnakeDir(whichSnake, t) ==
kDown)
583 else if (startState.GetSnakeDir(whichSnake, t) ==
kUp)
589 if (GetAddingDirection(x, y, endofSnakeX, endofSnakeY) !=
kNoDirection)
591 if (whichSnake == 0 && startState.GetNumSnakes() == 2)
593 startState.MakeSnakeLonger(whichSnake, GetAddingDirection(x, y, endofSnakeX, endofSnakeY));
597 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)+1);
598 startState.SetSnakeDir(whichSnake, startState.GetSnakeLength(whichSnake)-2, GetAddingDirection(x, y, endofSnakeX, endofSnakeY));
606 void SnakeBird::RemoveSnake(
int x,
int y,
int o,
int whichSnake)
608 int endofSnakeX =
GetX(startState.GetSnakeHeadLoc(whichSnake));
609 int endofSnakeY =
GetY(startState.GetSnakeHeadLoc(whichSnake));
610 if (startState.GetSnakeLength(whichSnake) >= 2 && startState.GetSnakeLength(whichSnake) <= 30)
612 for (
int t = 0; t <= startState.GetSnakeLength(whichSnake)-3; t++)
614 if (startState.GetSnakeDir(whichSnake, t) ==
kRight)
618 else if (startState.GetSnakeDir(whichSnake, t) ==
kLeft)
622 else if (startState.GetSnakeDir(whichSnake, t) ==
kDown)
626 else if (startState.GetSnakeDir(whichSnake, t) ==
kUp)
636 if (x == endofSnakeX && y == endofSnakeY && startState.GetSnakeLength(whichSnake) >= 3)
638 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-1);
640 else if (GetIndex(x, y) == startState.GetSnakeHeadLoc(whichSnake) && startState.GetNumSnakes() >= 2 && startState.GetNumSnakes() == 2)
642 std::vector<snakeDir> snakeBody;
643 int snakeHead = startState.GetSnakeHeadLoc(1);
644 for (
int t = 0; t <= startState.GetSnakeLength(1)-2; t++)
646 if (startState.GetSnakeDir(1, t) ==
kRight)
648 snakeBody.push_back(
kRight);
650 else if (startState.GetSnakeDir(1, t) ==
kLeft)
652 snakeBody.push_back(
kLeft);
654 else if (startState.GetSnakeDir(1, t) ==
kDown)
656 snakeBody.push_back(
kDown);
658 else if (startState.GetSnakeDir(1, t) ==
kUp)
660 snakeBody.push_back(
kUp);
663 startState.SetSnakeLength(whichSnake, 0);
664 startState.SetSnakeLength(whichSnake, snakeBody.size()+1);
665 startState.SetSnakeHeadLoc(whichSnake, snakeHead);
666 for (
int b = 0; b <= snakeBody.size(); b++)
667 startState.SetSnakeDir(whichSnake, b, snakeBody[b]);
668 startState.SetNumSnakes(startState.GetNumSnakes()-1);
672 std::vector<int> snakeBody;
673 int snakeBodyCounterX =
GetX(startState.GetSnakeHeadLoc(whichSnake));
674 int snakeBodyCounterY =
GetY(startState.GetSnakeHeadLoc(whichSnake));
675 for (
int t = 0; t <= startState.GetSnakeLength(whichSnake)-2; t++)
677 if (startState.GetSnakeDir(whichSnake, t) ==
kRight)
680 snakeBody.push_back(GetIndex(snakeBodyCounterX+1, snakeBodyCounterY));
682 else if (startState.GetSnakeDir(whichSnake, t) ==
kLeft)
685 snakeBody.push_back(GetIndex(snakeBodyCounterX-1, snakeBodyCounterY));
687 else if (startState.GetSnakeDir(whichSnake, t) ==
kDown)
690 snakeBody.push_back(GetIndex(snakeBodyCounterX, snakeBodyCounterY+1));
692 else if (startState.GetSnakeDir(whichSnake, t) ==
kUp)
695 snakeBody.push_back(GetIndex(snakeBodyCounterX, snakeBodyCounterY-1));
699 for (
int i = 0; i <= snakeBody.size()-1; i++)
701 if (GetIndex(x, y) == snakeBody[i])
703 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-snakeBody.size()-i);
710 if (x == endofSnakeX && y == endofSnakeY && startState.GetSnakeLength(whichSnake) >= 3)
712 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-1);
714 else if (GetIndex(x, y) == startState.GetSnakeHeadLoc(whichSnake) && startState.GetSnakeLength(whichSnake) >= 2 && startState.GetNumSnakes() >= 2)
716 std::vector<snakeDir> snakeBody;
717 int snakeHead = startState.GetSnakeHeadLoc(whichSnake);
718 for (
int t = 0; t <= startState.GetSnakeLength(whichSnake)-2; t++)
720 if (startState.GetSnakeDir(whichSnake, t) ==
kRight)
722 snakeBody.push_back(
kRight);
724 else if (startState.GetSnakeDir(whichSnake, t) ==
kLeft)
726 snakeBody.push_back(
kLeft);
728 else if (startState.GetSnakeDir(whichSnake, t) ==
kDown)
730 snakeBody.push_back(
kDown);
732 else if (startState.GetSnakeDir(whichSnake, t) ==
kUp)
734 snakeBody.push_back(
kUp);
737 startState.SetSnakeLength(whichSnake, 0);
738 startState.SetSnakeLength(whichSnake, snakeBody.size()+1);
739 startState.SetSnakeHeadLoc(whichSnake, snakeHead);
740 if (startState.GetSnakeLength(whichSnake) > 1)
742 for (
int b = 0; b <= snakeBody.size(); b++)
743 startState.SetSnakeDir(whichSnake, b, snakeBody[b]);
745 startState.SetNumSnakes(startState.GetNumSnakes()-1);
753 if (x == endofSnakeX && y == endofSnakeY)
755 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-1);
757 else if (GetIndex(x, y) == startState.GetSnakeHeadLoc(whichSnake) && startState.GetSnakeLength(whichSnake) >= 2)
759 startState.SetNumSnakes(startState.GetNumSnakes()-1);
763 std::vector<int> snakeBody;
764 int snakeBodyCounterX =
GetX(startState.GetSnakeHeadLoc(whichSnake));
765 int snakeBodyCounterY =
GetY(startState.GetSnakeHeadLoc(whichSnake));
766 for (
int t = 0; t <= startState.GetSnakeLength(whichSnake)-2; t++)
768 if (startState.GetSnakeDir(whichSnake, t) ==
kRight)
771 snakeBody.push_back(GetIndex(snakeBodyCounterX+1, snakeBodyCounterY));
773 else if (startState.GetSnakeDir(whichSnake, t) ==
kLeft)
776 snakeBody.push_back(GetIndex(snakeBodyCounterX-1, snakeBodyCounterY));
778 else if (startState.GetSnakeDir(whichSnake, t) ==
kDown)
781 snakeBody.push_back(GetIndex(snakeBodyCounterX, snakeBodyCounterY+1));
783 else if (startState.GetSnakeDir(whichSnake, t) ==
kUp)
786 snakeBody.push_back(GetIndex(snakeBodyCounterX, snakeBodyCounterY-1));
790 for (
int i = 0; i <= snakeBody.size()-1; i++)
792 if (GetIndex(x, y) == snakeBody[i])
794 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-snakeBody.size()-i);
801 if (x == endofSnakeX && y == endofSnakeY && startState.GetSnakeLength(whichSnake) >= 3)
803 startState.SetSnakeLength(whichSnake, startState.GetSnakeLength(whichSnake)-1);
805 if (GetIndex(x, y) == startState.GetSnakeHeadLoc(whichSnake) && startState.GetSnakeLength(whichSnake) >= 2)
807 startState.SetSnakeLength(whichSnake, 0);
808 startState.SetNumSnakes(startState.GetNumSnakes()-1);
814 std::vector<snakeDir>
LoadSnake(std:: vector<snakeDir> snakeBod,
int width,
int pos,std::vector<char> lvl)
816 bool snakeBuilt =
false;
820 if (lvl[pos+1] == 1+lvl[pos]){
821 snakeBod.push_back(
kRight);
825 else if (lvl[pos-1] == 1+lvl[pos])
827 snakeBod.push_back(
kLeft);
831 else if (lvl[pos+
width+1] == 1+lvl[pos])
833 snakeBod.push_back(
kDown);
837 else if (lvl[pos-
width-1] == 1+lvl[pos])
839 snakeBod.push_back(
kUp);
858 bool SnakeBird::Load(
const char *filename)
862 std::ifstream infile;
863 infile.open(filename);
865 printf(
"File could not be opened.\n");
869 if (infile.is_open()){
876 getline(infile, hLine);
880 sscanf(hLine.c_str(),
"snake%dx%d", &wWidth, &wHeight);
888 portal1Loc = portal2Loc = -1;
890 std::fill_n(&world[0], 512,
kEmpty);
893 for (
int x = 0; x < objects.size(); x++)
898 this->
width = wWidth;
900 for (
int x = 0; x <
width; x++)
903 std::vector<char> lvlary;
904 while (infile.get(ch)) {
906 lvlary.push_back(ch);
909 std:: vector<snakeDir> bod;
910 bool snakeBuilt =
false;
911 bool madePortal =
false;
912 for(
int a = 0; a <= lvlary.size(); a++)
937 case '1': SetGroundType(x, y,
kBlock1); x++;
break;
938 case '2': SetGroundType(x, y,
kBlock2); x++;
break;
939 case '3': SetGroundType(x, y,
kBlock3); x++;
break;
940 case '4': SetGroundType(x, y,
kBlock4); x++;
break;
941 case '\n': x = 0; y++;
break;
953 bod.push_back(
kLeft);
962 bod.push_back(
kDown);
987 std::cout <<
"Error loading level.";
996 bool SnakeBird::Save(
const char *filename)
1001 std::string SnakeBird::Code(
int v)
const
1004 static const char* digits =
"abcdefghijklmnopqrstuvwxyz";
1010 res += digits[v%26];
1015 int SnakeBird::DeCode(
const std::string &s,
size_t offset)
const
1022 switch (s[offset+x])
1024 case 'a': val = val*26+0;
break;
1025 case 'b': val = val*26+1;
break;
1026 case 'c': val = val*26+2;
break;
1027 case 'd': val = val*26+3;
break;
1028 case 'e': val = val*26+4;
break;
1029 case 'f': val = val*26+5;
break;
1030 case 'g': val = val*26+6;
break;
1031 case 'h': val = val*26+7;
break;
1032 case 'i': val = val*26+8;
break;
1033 case 'j': val = val*26+9;
break;
1034 case 'k': val = val*26+10;
break;
1035 case 'l': val = val*26+11;
break;
1036 case 'm': val = val*26+12;
break;
1037 case 'n': val = val*26+13;
break;
1038 case 'o': val = val*26+14;
break;
1039 case 'p': val = val*26+15;
break;
1040 case 'q': val = val*26+16;
break;
1041 case 'r': val = val*26+17;
break;
1042 case 's': val = val*26+18;
break;
1043 case 't': val = val*26+19;
break;
1044 case 'u': val = val*26+20;
break;
1045 case 'v': val = val*26+21;
break;
1046 case 'w': val = val*26+22;
break;
1047 case 'x': val = val*26+23;
break;
1048 case 'y': val = val*26+24;
break;
1049 case 'z': val = val*26+25;
break;
1050 default:
return -1;
break;
1060 std::string SnakeBird::EncodeLevel()
const
1062 std::string encoding;
1064 encoding += std::to_string(
width);
1066 encoding += std::to_string(
height);
1070 encoding += Code(exitLoc);
1077 encoding += Code(i);
1085 encoding += Code(i);
1090 if (fruit.size() > 0)
1092 for (
auto i : fruit)
1094 encoding += Code(i);
1099 if (portal1Loc != -1 && portal2Loc != -1)
1102 encoding += Code(portal1Loc);
1103 encoding += Code(portal2Loc);
1107 for (
int x = 0; x < objects.size(); x++)
1109 if (objects[x].size() > 0)
1111 for (
int i = 0; i < objects[x].size(); i++)
1113 int index = GetIndex(
GetX(objects[x][i])+
GetX(startState.GetObjectLocation(x)),
1114 GetY(objects[x][i])+
GetY(startState.GetObjectLocation(x)));
1115 encoding += Code(index);
1120 for (
int x = 0; x < startState.GetNumSnakes(); x++)
1123 encoding+=Code(startState.GetSnakeHeadLoc(x));
1125 for (
int y = 0; y < startState.GetSnakeLength(x)-1; y++)
1127 switch (startState.GetSnakeDir(x, y))
1129 case kLeft: encoding+=
"L";
break;
1130 case kRight: encoding+=
"R";
break;
1131 case kDown: encoding+=
"D";
break;
1132 case kUp: encoding+=
"U";
break;
1143 bool SnakeBird::DecodeLevel(
const std::string &encoding)
1145 portal1Loc = portal2Loc = -1;
1147 std::fill_n(&world[0], 512,
kEmpty);
1150 for (
int x = 0; x < objects.size(); x++)
1155 int cnt = sscanf(encoding.c_str(),
"%db%dE", &
width, &
height);
1156 if (cnt != 2 ||
width < 5 || height < 5 || width*height > 512)
1157 { Reset();
return false; }
1159 size_t start = encoding.find_first_of(
"E");
1160 if (start==std::string::npos)
1161 { Reset(); printf(
"F1\n");
return false; }
1164 exitLoc = DeCode(encoding, start);
1170 SetGroundType(exitLoc,
kExit);
1173 if (start >= encoding.size() || encoding[start] !=
'G')
1174 { Reset(); printf(
"F2\n");
return false; }
1177 while (start < encoding.size() && encoding[start] !=
'K')
1179 int next = DeCode(encoding, start);
1181 { Reset(); printf(
"F3\n");
return false; }
1187 if (start >= encoding.size() || encoding[start] !=
'K')
1188 { Reset(); printf(
"F4\n");
return false; }
1191 while (start < encoding.size() && encoding[start] !=
'F')
1193 int next = DeCode(encoding, start);
1195 { Reset(); printf(
"F5\n");
return false; }
1200 if (start >= encoding.size() || encoding[start] !=
'F')
1201 { Reset(); printf(
"F6\n");
return false; }
1204 while (start < encoding.size() &&
1205 encoding[start] !=
'P' && encoding[start] !=
'B' && encoding[start] !=
'S')
1207 int next = DeCode(encoding, start);
1209 { Reset(); printf(
"F7\n");
return false; }
1211 SetGroundType(next,
kFruit);
1215 if (start >= encoding.size())
1216 { Reset(); printf(
"F8\n");
return false; }
1217 if (encoding[start] ==
'P' && start+1+2*
codeSize <= encoding.size())
1219 SetGroundType(DeCode(encoding, start+1),
kPortal1);
1227 while (start < encoding.size() && encoding[start] ==
'B')
1232 int next = DeCode(encoding, start);
1234 { Reset(); printf(
"F9\n");
return false; }
1235 SetGroundType(next, blocks[whichBlock]);
1237 }
while (start < encoding.size() && encoding[start] !=
'B' && encoding[start] !=
'S');
1241 if (encoding[start] !=
'S')
1242 { Reset(); printf(
"F10\n");
return false; }
1247 while (start < encoding.size())
1249 std::vector<snakeDir> body;
1252 int next = DeCode(encoding, start);
1254 { Reset(); printf(
"F11\n");
return false; }
1261 switch (encoding[start])
1263 case 'U': body.push_back(
kUp);
break;
1264 case 'D': body.push_back(
kDown);
break;
1265 case 'L': body.push_back(
kLeft);
break;
1266 case 'R': body.push_back(
kRight);
break;
1272 if (start >= encoding.size())
1275 if (body.size() == 0)
1276 { Reset(); printf(
"F12\n");
return false; }
1278 startState.SetNumSnakes(whichSnake+1);
1279 startState.SetSnakeHeadLoc(whichSnake, next);
1280 startState.SetSnakeLength(whichSnake, body.size()+1);
1281 for (
int x = 0; x < body.size(); x++)
1282 startState.SetSnakeDir(whichSnake, x, body[x]);
1284 }
while (start < encoding.size());
1286 for (
int x = 0; x <
width; x++)
1296 void SnakeBird::GetSuccessors(
const SnakeBirdState &nodeID, std::vector<SnakeBirdState> &neighbors)
const
1298 static std::vector<SnakeBirdAction> acts;
1299 GetActions(nodeID, acts);
1301 for (
auto &a : acts)
1328 neighbors.push_back(s);
1338 static std::vector<SnakeBirdAction> acts;
1339 GetActions(s, acts);
1340 for (
auto &act : acts)
1356 for (
int x = 0; x < len; x++)
1376 std::fill_n(&render[0], 512,
kEmpty);
1388 render[
loc] = obj[snake];
1392 for (
int x = 0; x < len; x++)
1404 render[
loc] = obj[snake];
1410 for (
size_t f = 0; f < fruit.size(); f++)
1413 render[fruit[f]] =
kFruit;
1417 for (
int x = 0; x < 4; x++)
1424 for (
int i = 0; i < objects[x].size(); i++)
1440 void SnakeBird::GetActions(
const SnakeBirdState &s, std::vector<SnakeBirdAction> &actions)
const
1445 bool success = Render(s);
1468 actions.push_back(a);
1476 render[
loc-1] != obj[snake])
1481 if (CanPush(s, snake, render[
loc-1],
kUp, a))
1484 actions.push_back(a);
1490 actions.push_back(a);
1506 actions.push_back(a);
1512 actions.push_back(a);
1528 actions.push_back(a);
1532 std::cout << +world[
loc-
height] << std::endl;
1535 actions.push_back(a);
1559 case kSnake1:
if (snake == 0)
return false; pushed = 0;
break;
1560 case kSnake2:
if (snake == 1)
return false; pushed = 1;
break;
1561 case kSnake3:
if (snake == 2)
return false; pushed = 2;
break;
1562 case kSnake4:
if (snake == 3)
return false; pushed = 3;
break;
1563 case kBlock1: pushed = 4;
break;
1564 case kBlock2: pushed = 5;
break;
1565 case kBlock3: pushed = 6;
break;
1566 case kBlock4: pushed = 7;
break;
1567 default:
return false;
break;
1570 if ((a.
pushed>>pushed)&0x1)
1584 case kUp:
if (
loc == 0)
return false;
loc-=1;
break;
1595 if (!CanPush(s, snake, render[
loc], dir, a))
1600 for (
int x = 0; x < len; x++)
1606 case kUp:
if (
loc == 0)
return false;
loc-=1;
break;
1618 if (!CanPush(s, snake, render[
loc], dir, a))
1623 else if (pushed >= 4)
1630 for (
int x = 0; x < objects[pushed].size(); x++)
1632 int pieceLoc = objects[pushed][x];
1633 pieceLoc = GetIndex(
GetX(objects[pushed][x])+
GetX(
loc),
1639 case kUp:
if (pieceLoc == 0)
return false; pieceLoc-=1;
break;
1640 case kDown:
if (pieceLoc+1 ==
width*
height)
return false; pieceLoc+=1;
break;
1644 if (render[pieceLoc]==
kFruit)
1649 if (!CanPush(s, snake, render[pieceLoc], dir, a))
1663 bool didExit =
false;
1702 for (
int i = 0; i < 4 && (a.
pushed>>i); i++)
1726 for (
int i = 4; i < 8 && (a.
pushed>>i); i++)
1747 uint8_t falling = 0;
1750 for (
int i = 0; i < 8; i++)
1760 if (CanPush(s, -1, objs[i],
kDown, move))
1770 bool hitExit =
false;
1771 for (
int i = 0; i < 8; i++)
1773 if (i < 4 && ((falling>>i)&0x1))
1782 if (i >= 4 && ((falling>>i)&0x1))
1789 for (
size_t i = 0; i < objects.size(); i++)
1792 if (objLoc ==
kDead)
1794 int objectY =
GetY(objLoc);
1795 for (
size_t j = 0; j < objects[i].size(); j++)
1834 case kUp: offset = -1; opposite =
kDown;
break;
1835 case kDown: offset = 1; opposite =
kUp;
break;
1836 default: printf(
"Warning: Applied illegal action\n");
return true;
1842 step.
anim = DoFirstMovement(step.
a, offset, opposite, s);
1849 for (
int i = 0; i < 4; i++)
1882 bool success = Render(s);
1892 auto didTeleport = HandleTeleports(s, step.
a, lastAction, opposite, step);
1920 step.
anim = DoFall(step.
a, s);
1929 for (
int i = 0; i < 4; i++)
1961 case kUp: offset = -1; opposite =
kDown;
break;
1962 case kDown: offset = 1; opposite =
kUp;
break;
1963 default: printf(
"Warning: Applied illegal action\n");
return;
1969 step.
anim = DoFirstMovement(a, offset, opposite, s);
1974 for (
int i = 0; i < 4; i++)
1995 bool success = Render(s);
2001 auto didTeleport = HandleTeleports(s, a,
kDown,
kUp, step);
2016 auto didTeleport = HandleTeleports(s, a, lastAction, opposite, step);
2040 step.
anim = DoFall(a, s);
2048 bool success = Render(s);
2052 for (
int i = 0; i < 4; i++)
2070 bool didTeleport =
false;
2071 bool didExit =
false;
2074 for (
int i = 0; i < 4 && (a.
pushed>>i); i++)
2096 case kUp: piece-=1;
break;
2097 case kDown: piece+=1;
break;
2101 if (piece == portal1Loc)
2106 else if (piece == portal2Loc)
2117 if (x > 0 && s.
GetSnakeDir(snake, x-1) == opposite)
2131 int newPiece = GetIndex(
GetX(newloc)+xChange,
GetY(newloc)+yChange);
2141 case kUp: newPiece-=1;
break;
2142 case kDown: newPiece+=1;
break;
2146 if (
GetX(newPiece) < 0 ||
2148 GetY(newPiece) < 0 ||
2156 render[newPiece] != objs[snake]) ||
2159 (render[newPiece] ==
kFruit))
2167 int offsetFromPortalX =
GetX(newloc)+xChange;
2168 int offsetFromPortalY =
GetY(newloc)+yChange;
2173 bool success = Render(s);
2174 assert(success ==
true);
2187 for (
int i = 4; i < 8 && (a.
pushed>>i) && !didTeleport; i++)
2193 if (newloc ==
kDead)
2195 for (
size_t x = 0; x < objects[object].size(); x++)
2197 int piece = GetIndex(
GetX(objects[
object][x])+
GetX(newloc),
2198 GetY(objects[
object][x])+
GetY(newloc));
2200 if (piece == portal1Loc)
2205 else if (piece == portal2Loc)
2224 if (p1-1 >= 0 && render[p1-1] == objs[i])
2228 if (p1+1 <
width*
height && render[p1+1] == objs[i])
2243 for (
size_t v = 0; v < objects[object].size(); v++)
2245 if (
GetX(newloc)+
GetX(objects[
object][v])+xChange < 0 ||
2247 GetY(newloc)+
GetY(objects[
object][v])+yChange < 0 ||
2253 int newPiece = GetIndex(
GetX(newloc)+
GetX(objects[
object][v])+xChange,
2254 GetY(newloc)+
GetY(objects[
object][v])+yChange);
2265 int offsetFromPortalX =
GetX(newloc)+xChange;
2266 int offsetFromPortalY =
GetY(newloc)+yChange;
2270 bool success = Render(s);
2271 assert(success ==
true);
2279 if (didExit && didTeleport)
2289 SetGroundType(
GetX(index),
GetY(index), o);
2295 void SnakeBird::RemoveBlock(
int x,
int y)
2297 for (
int which = 0; which < 4; which++)
2299 if (objects[which].size() <= 0)
2302 int xOffset = 0, yOffset = 0;
2303 xOffset =
GetX(startState.GetObjectLocation(which));
2304 yOffset =
GetY(startState.GetObjectLocation(which));
2306 for (
size_t i = 0; i < objects[which].size(); i++)
2308 if (
GetX(objects[which][i])+xOffset == x &&
2309 GetY(objects[which][i])+yOffset == y)
2311 objects[which][i] = objects[which].back();
2312 objects[which].pop_back();
2317 if (objects[which].size() <= 0)
2325 for (
size_t i = 0; i < objects[which].size(); i++)
2327 newX =
std::min(newX,
GetX(objects[which][i])+xOffset);
2328 newY =
std::min(newY,
GetY(objects[which][i])+yOffset);
2330 startState.SetObjectLocation(which, GetIndex(newX, newY));
2331 for (
size_t i = 0; i < objects[which].size(); i++)
2334 objects[which][i] = GetIndex(
GetX(objects[which][i])+xOffset - newX,
2335 GetY(objects[which][i])+yOffset - newY);
2347 printf(
"!!WARNING: Cannot change map without enabling editing!!\n");
2353 printf(
"Error - cannot add terrain at bottom of map\n");
2375 assert(!
"Can't get here - object is a block");
2378 assert(which != -1);
2381 int newX = x, newY=y;
2382 int xOffset = 0, yOffset = 0;
2383 if (objects[which].size() > 0)
2385 xOffset =
GetX(startState.GetObjectLocation(which));
2386 yOffset =
GetY(startState.GetObjectLocation(which));
2390 for (
int i = 0; i < objects[which].size(); i++)
2392 newX =
std::min(newX,
GetX(objects[which][i])+xOffset);
2393 newY =
std::min(newY,
GetY(objects[which][i])+yOffset);
2395 startState.SetObjectLocation(which, GetIndex(newX, newY));
2396 for (
int i = 0; i < objects[which].size(); i++)
2399 objects[which][i] = GetIndex(
GetX(objects[which][i])+xOffset - newX,
2400 GetY(objects[which][i])+yOffset - newY);
2403 objects[which].push_back(GetIndex(x-newX, y-newY));
2410 if ((portal1Loc == -1) || (portal1Loc == GetIndex(x, y)))
2414 else if ((portal2Loc == -1) || (portal2Loc == GetIndex(x, y)))
2419 printf(
"error cannot determine portal type");
2423 auto oldTerrainType = world[GetIndex(x, y)];
2424 world[GetIndex(x, y)] = o;
2431 if (oldTerrainType ==
kFruit)
2433 std::vector<int>::iterator tor = std::find(fruit.begin(), fruit.end(), GetIndex(x, y));
2434 if (tor != fruit.end())
2440 fruit.push_back(GetIndex(x, y));
2441 if (oldTerrainType ==
kExit)
2445 if (exitLoc != -1 && exitLoc != GetIndex(x, y))
2447 exitLoc = GetIndex(x, y);
2451 if (portal1Loc != -1 && portal1Loc != GetIndex(x, y))
2452 world[portal1Loc] =
kEmpty;
2453 portal1Loc = GetIndex(x, y);
2457 if (portal2Loc != -1 && portal2Loc != GetIndex(x, y))
2458 world[portal2Loc] =
kEmpty;
2459 portal2Loc = GetIndex(x, y);
2461 if (oldTerrainType ==
kPortal1 && portal1Loc == GetIndex(x, y))
2463 world[portal1Loc] =
kEmpty;
2466 if (oldTerrainType ==
kPortal2 && portal2Loc == GetIndex(x, y))
2468 world[portal2Loc] =
kEmpty;
2473 int SnakeBird::GetNumPortals()
2476 if (portal1Loc != -1)
2478 if (portal2Loc != -1)
2487 int SnakeBird::GetFruitOffset(
int index)
const
2489 for (
int x = 0; x < fruit.size(); x++)
2490 if (fruit[x] == index)
2502 return world[GetIndex(x, y)];
2510 if (GetGroundType(x, y) !=
kEmpty)
2511 return GetGroundType(x, y);
2512 bool success = Render(s);
2516 return render[GetIndex(x, y)];
2520 int SnakeBird::GetIndex(
int x,
int y)
const
2535 int SnakeBird::Distance(
int index1,
int index2)
2537 int x1 =
GetX(index1);
2538 int y1 =
GetY(index1);
2539 int x2 =
GetX(index2);
2540 int y2 =
GetY(index2);
2541 return abs(x1-x2)+abs(y1-y2);
2558 float radius = GetRadius()*0.95;
2564 switch ((
GetX(x)*13*+11*
GetY(x))%6)
2601 double radius = GetRadius()*0.95;
2619 double radius = GetRadius()*0.95;
2621 double offset1 = (sin(time*1.0));
2622 double offset2 = (sin(time*1.5));
2623 double offset3 = (sin(time*2.0));
2624 double offset4 = (sin(time*2.5));
2633 const float rows = 5;
2634 const float counts[] = {3, 4, 3, 2, 1};
2636 float grapeRadius = GetRadius()*0.15f;
2637 for (
int t = 0; t < rows; t++)
2639 for (
int v = 0; v < counts[t]; v++)
2642 tmp.
y -= rows*grapeRadius;
2643 tmp.
y += 2*t*grapeRadius;
2644 tmp.
x = tmp.
x-grapeRadius*(counts[t]-1)+v*grapeRadius*2;
2645 tmp.
x += sin(time*1.1+(t+v)*0.1)*GetRadius()*0.1;
2646 tmp.
y += cos(time*0.95+(t+v)*0.1)*GetRadius()*0.1;
2655 double radius = GetRadius()*0.95;
2656 double localTime = time;
2658 double offset1 = (sin(localTime*1.0))*180;
2659 double offset2 = (sin(localTime*1.5))*180;
2660 double offset3 = (sin(localTime*2.0))*180;
2676 float radius = GetRadius()*0.95;
2681 radius = GetRadius();
2683 display.FrameSquare(p, radius-radius*0.3, objColors[0], radius*0.6);
2688 radius = GetRadius();
2690 display.FrameSquare(p, radius-radius*0.3, objColors[1], radius*0.6);
2695 radius = GetRadius();
2697 display.FrameSquare(p, radius-radius*0.3, objColors[2], radius*0.6);
2702 radius = GetRadius();
2704 display.FrameSquare(p, radius-radius*0.3, objColors[3], radius*0.6);
2719 display.FillTriangle({p.
x-radius/2.0f, p.
y}, {p.
x-radius/4.0f, p.
y-radius/2}, {p.
x, p.
y},
Colors::darkred);
2720 display.FillTriangle({p.
x+radius/2.0f, p.
y}, {p.
x+radius/4.0f, p.
y-radius/2}, {p.
x, p.
y},
Colors::darkred);
2722 display.FillTriangle({p.
x-radius/2.0f, p.
y}, {p.
x-radius, p.
y+radius/4}, {p.
x-radius/2.0f, p.
y+radius/2},
Colors::darkred);
2723 display.FillTriangle({p.
x-radius/2.0f, p.
y+radius/2}, {p.
x-radius, p.
y+3*radius/4}, {p.
x-radius/2.0f, p.
y+radius},
Colors::darkred);
2725 display.FillTriangle({p.
x+radius/2.0f, p.
y}, {p.
x+radius, p.
y+radius/4}, {p.
x+radius/2.0f, p.
y+radius/2},
Colors::darkred);
2726 display.FillTriangle({p.
x+radius/2.0f, p.
y+radius/2}, {p.
x+radius, p.
y+3*radius/4}, {p.
x+radius/2.0f, p.
y+radius},
Colors::darkred);
2732 double radius = GetRadius()*0.95;
2733 double offset1 = (sin(time*1.0));
2734 double offset2 = (sin(time*1.5));
2735 double offset3 = (sin(time*2.0));
2736 double offset4 = (sin(time*2.5));
2737 display.FillCircle(p, radius+offset1*radius*0.25,
Colors::red);
2738 display.FillCircle(p, radius*0.75+offset2*radius*0.2,
Colors::blue);
2739 display.FillCircle(p, radius*0.5+offset3*radius*0.15,
Colors::green);
2740 display.FillCircle(p, radius*0.25+offset4*radius*0.1,
Colors::purple);
2745 const float rows = 5;
2746 const float counts[] = {3, 4, 3, 2, 1};
2747 float grapeRadius = GetRadius()*0.15f;
2748 for (
int t = 0; t < rows; t++)
2750 for (
int v = 0; v < counts[t]; v++)
2753 tmp.
y -= rows*grapeRadius;
2754 tmp.
y += 2*t*grapeRadius;
2755 tmp.
x = tmp.
x-grapeRadius*(counts[t]-1)+v*grapeRadius*2;
2756 tmp.
x += sin(time*1.1+(t+v)*0.1)*GetRadius()*0.1;
2757 tmp.
y += cos(time*0.95+(t+v)*0.1)*GetRadius()*0.1;
2758 display.FillCircle(tmp, grapeRadius*1.1,
Colors::purple*sin(time*1.95+v+t));
2765 double radius = GetRadius()*0.95;
2766 double localTime = time;
2768 double offset1 = (sin(localTime*1.0))*180;
2769 double offset2 = (sin(localTime*1.5))*180;
2770 double offset3 = (sin(localTime*2.0))*180;
2773 display.FillNGon(p, radius*0.25, 5, 54+offset3,
Colors::red);
2780 float smallRadius = 0.75*GetRadius();
2784 display.FillRect(r, color);
2787 r.
left+=smallRadius;
2788 r.
right-=smallRadius;
2789 display.FillRect(r, color);
2791 display.FillCircle(p+
Graphics::point(smallRadius-GetRadius(), smallRadius-GetRadius()), smallRadius, color);
2792 display.FillCircle(p+
Graphics::point(smallRadius-GetRadius(), -smallRadius+GetRadius()), smallRadius, color);
2793 display.FillSquare(p+
Graphics::point(-GetRadius()/2+GetRadius(), GetRadius()/2-GetRadius()), GetRadius()/2, color);
2794 display.FillSquare(p+
Graphics::point(-GetRadius()/2+GetRadius(), -GetRadius()/2+GetRadius()), GetRadius()/2, color);
2796 float eyescale = 1+snake/5.0;
2800 p.
x+=GetRadius()*0.2;
2801 display.FillCircle(p, GetRadius()*0.2*eyescale, tmp);
2802 p.
x-=2*GetRadius()*0.2;
2803 display.FillCircle(p, GetRadius()*0.2*eyescale, tmp);
2804 p.
x+=2*GetRadius()*0.2;
2807 display.FillCircle(p, GetRadius()*0.1*eyescale,
Colors::black);
2808 p.
x-=2*GetRadius()*0.2;
2809 display.FillCircle(p, GetRadius()*0.1*eyescale,
Colors::black);
2811 p.
x+=GetRadius()*0.2;
2812 p.
y+=2*GetRadius()*0.25;
2820 float smallRadius = 0.75*GetRadius();
2824 display.FillRect(r, color);
2827 r.
left+=smallRadius;
2828 r.
right-=smallRadius;
2829 display.FillRect(r, color);
2831 display.FillCircle(p+
Graphics::point(smallRadius-GetRadius(), smallRadius-GetRadius()), smallRadius, color);
2832 display.FillCircle(p+
Graphics::point(smallRadius-GetRadius(), -smallRadius+GetRadius()), smallRadius, color);
2833 display.FillSquare(p+
Graphics::point(-GetRadius()/2+GetRadius(), GetRadius()/2-GetRadius()), GetRadius()/2, color);
2834 display.FillSquare(p+
Graphics::point(-GetRadius()/2+GetRadius(), -GetRadius()/2+GetRadius()), GetRadius()/2, color);
2836 float eyescale = 1+snake/5.0;
2840 p.
x+=GetRadius()*0.2;
2841 display.FillCircle(p, GetRadius()*0.2*eyescale, tmp);
2842 p.
x-=2*GetRadius()*0.2;
2843 display.FillCircle(p, GetRadius()*0.2*eyescale, tmp);
2844 p.
x+=2*GetRadius()*0.2;
2847 display.FillCircle(p, GetRadius()*0.1*eyescale,
Colors::black);
2848 p.
x-=2*GetRadius()*0.2;
2849 display.FillCircle(p, GetRadius()*0.1*eyescale,
Colors::black);
2851 p.
x+=GetRadius()*0.2;
2852 p.
y+=2*GetRadius()*0.25;
2863 for (
int x = -2; x <=
width+1; x++)
2865 auto p = GetCenter(x,
height-1);
2866 p.y += GetRadius()+0.25*GetRadius()*sin(x*4.0/
width+time*0.43);
2867 p.x += fmod(time*0.25, 2)*GetRadius();
2871 if (portal1Loc != -1)
2873 double radius = GetRadius()*0.95;
2875 double offset1 = (sin(time*1.0));
2876 double offset2 = (sin(time*1.5));
2877 double offset3 = (sin(time*2.0));
2878 double offset4 = (sin(time*2.5));
2884 if (portal2Loc != -1)
2886 double radius = GetRadius()*0.95;
2888 double offset1 = (sin(time*1.0+0.1));
2889 double offset2 = (sin(time*1.5+0.1));
2890 double offset3 = (sin(time*2.0+0.1));
2891 double offset4 = (sin(time*2.5+0.1));
2902 x = (p.
x+1.0-GetRadius())/(2.0*GetRadius())+0.5;
2903 y = (p.
y+1.0-GetRadius())/(2.0*GetRadius())+0.5;
2904 if (x >= 0 && x < width && y >= 0 && y <
height)
2912 p.
x = -1+2*x*GetRadius()+GetRadius();
2913 p.
y = -1+2*y*GetRadius()+GetRadius();
2917 float SnakeBird::GetRadius()
const
2924 Draw(display, s, -1);
2929 Draw(display, s, active, 0);
2934 int snake,
bool isActive,
double percentComplete)
const
2939 int x =
GetX(index);
2940 int y =
GetY(index);
2944 float timePerSegment = 1.0f/len;
2945 float drawnTime = 0;
2946 int nextIn = percentComplete*len;
2949 int prevx = x, prevy = y;
2950 for (
int t = nextIn; t < len; t++)
2956 case kUp: y-=1;
break;
2957 case kDown: y+=1;
break;
2958 case kRight: x+=1;
break;
2959 case kLeft: x-=1;
break;
2962 bool tail = (t+1==len);
2967 rgbColor color = snakeColors[snake]*(((lastx+lasty)&1)?0.8:1.0);
2973 float perc = percentComplete*len-nextIn;
2974 p = p2*perc+p*(1-perc);
2977 DrawSnakeSegment(display, p, color,
2988 int snake,
bool isActive,
double percentComplete)
const
2993 int x =
GetX(index);
2994 int y =
GetY(index);
3000 bool deadSegment = IsOnSpikes(s, snake);
3003 for (
int t = 0; t < len; t++)
3007 case kUp: y-=1;
break;
3008 case kDown: y+=1;
break;
3009 case kRight: x+=1;
break;
3010 case kLeft: x-=1;
break;
3016 rgbColor color = snakeColors[snake]*(((++cnt+len)&1)?0.8:1.0);
3022 p = p*percentComplete + p2*(1-percentComplete);
3028 DrawSnakeSegment(display, p, color,
3047 p = p*percentComplete + p2*(1-percentComplete);
3049 rgbColor color = snakeColors[snake]*((len%2)?0.8:1.0);
3051 DrawSnakeSegment(display, p, color,
true,
false, isActive,
kUp, s.
GetSnakeDir(snake, 0), snake, deadSegment);
3056 int snake,
bool isActive,
double percentComplete)
const
3061 int x =
GetX(index);
3062 int y =
GetY(index);
3066 bool deadSegment = IsOnSpikes(s, snake);
3070 int cnt = ateFruit?0:1;
3075 for (
int t = 0; t < len-1; t++)
3079 if (percentComplete < 0.1 && t == 0)
3081 rgbColor color = snakeColors[snake]*(((++cnt+len)&1)?0.8:1.0);
3086 DrawSnakeSegment(display, p, color,
3091 toDir, snake, deadSegment);
3096 lastx = x; lasty = y;
3099 case kUp: y-=1;
break;
3100 case kDown: y+=1;
break;
3101 case kRight: x+=1;
break;
3102 case kLeft: x-=1;
break;
3112 p = p*percentComplete + p2*(1-percentComplete);
3113 color = snakeColors[snake];
3116 DrawSnakeSegment(display, p, color,
false,
true,
false, old.
GetSnakeDir(snake, len-2),
kUp, snake, deadSegment);
3120 rgbColor color = snakeColors[snake]*(((++cnt+len)&1)?0.8:1.0);
3123 bool deadSegment = GetGroundType(x, y)==
kSpikes;
3124 DrawSnakeSegment(display, p, color,
false,
true,
false, old.
GetSnakeDir(snake, len-2),
kUp, snake, deadSegment);
3136 p = p*percentComplete + p2*(1-percentComplete);
3137 rgbColor color = snakeColors[snake]*((len%2)?1.0:0.8);
3140 DrawSnakeSegment(display, p, color,
true,
false, isActive,
kUp, s.
GetSnakeDir(snake, 0), snake, deadSegment);
3147 int active,
double percentComplete,
double globalTime)
const
3153 static std::vector<Graphics::point> points;
3154 for (
int x = 0; x < 4; x++)
3156 double radius = GetRadius();
3157 if (editing ==
true)
3158 { printf(
"WARNING: editing not turned off.\n"); }
3162 for (
int i = 0; i < objects[x].size(); i++)
3168 p = p*percentComplete+p2*(1-percentComplete);
3169 display.
FrameSquare(p, radius-radius*0.3, objColors[x], radius*0.6);
3170 if (!objectFullyConnected[x])
3171 points.push_back(p);
3173 if (points.size() > 0)
3175 for (
int z = 0; z < points.size(); z++)
3177 for (
int y = z+1; y < points.size(); y++)
3179 if (
fequal(points[z].x, points[y].x))
3182 points[z].y+GetRadius()-radius*0.3*2,
3183 points[y].x+GetRadius()*0.2f,
3184 points[y].y-GetRadius()+radius*0.3*2);
3185 display.
FillRect(r, objColors[x]*0.5);
3187 else if (
fequal(points[z].y, points[y].y))
3190 points[z].y-GetRadius()*0.2f,
3191 points[y].x-GetRadius()+radius*0.3*2,
3192 points[y].y+GetRadius()*0.2f);
3193 display.
FillRect(r, objColors[x]*0.5);
3215 DrawTranslatingSnake(display, s, s, snake, (active==-1)||(active==snake), percentComplete);
3219 DrawSnakeEnteringGoal(display, old, snake, (active==-1)||(active==snake), percentComplete);
3224 DrawMovingSnake(display, old, s, snake, (active==-1)||(active==snake), percentComplete);
3230 DrawTranslatingSnake(display, old, s, snake, (active==-1)||(active==snake), percentComplete);
3235 DrawMovingSnake(display, old, s, snake, (active==-1)||(active==snake), percentComplete);
3240 for (
int x = 0; x < fruit.size(); x++)
3244 const float rows = 5;
3245 const float counts[] = {3, 4, 3, 2, 1};
3247 float grapeRadius = GetRadius()*0.15f;
3248 for (
int t = 0; t < rows; t++)
3250 for (
int v = 0; v < counts[t]; v++)
3253 tmp.
y -= rows*grapeRadius;
3254 tmp.
y += 2*t*grapeRadius;
3255 tmp.
x = tmp.
x-grapeRadius*(counts[t]-1)+v*grapeRadius*2;
3256 tmp.
x += sin(globalTime*1.1+(t+v)*0.1)*GetRadius()*0.1;
3257 tmp.
y += cos(globalTime*0.95+(t+v)*0.1)*GetRadius()*0.1;
3268 double radius = GetRadius()*0.95;
3269 double time = globalTime;
3272 radius = radius+0.25*radius*(1+sin(globalTime*2.5));
3278 double offset1 = (sin(time*1.0))*180;
3279 double offset2 = (sin(time*1.5))*180;
3280 double offset3 = (sin(time*2.0))*180;
3290 Draw(display, s, s, active, 0, globalTime);
3300 float smallRadius = 0.75*GetRadius();
3307 r.
left+=smallRadius;
3308 r.
right-=smallRadius;
3311 if ((!head && (dirFrom ==
kDown || dirFrom ==
kRight)) ||
3312 (!tail && (dirTo ==
kUp || dirTo ==
kLeft)))
3320 if ((!head && (dirFrom ==
kUp || dirFrom ==
kRight)) ||
3321 (!tail && (dirTo ==
kDown || dirTo ==
kLeft)))
3329 if ((!head && (dirFrom ==
kDown || dirFrom ==
kLeft)) ||
3330 (!tail && (dirTo ==
kUp || dirTo ==
kRight)))
3338 if ((!head && (dirFrom ==
kUp || dirFrom ==
kLeft)) ||
3349 float eyescale = 1+snake/5.0;
3356 p.
x+=GetRadius()*0.2;
3357 display.
FillCircle(p, GetRadius()*0.2*eyescale, tmp);
3358 p.
x-=2*GetRadius()*0.2;
3359 display.
FillCircle(p, GetRadius()*0.2*eyescale, tmp);
3360 p.
x+=2*GetRadius()*0.2;
3365 p.
x-=2*GetRadius()*0.2;
3370 p.
x+=GetRadius()*0.2;
3371 p.
y+=2*GetRadius()*0.25;