Owen Cavender 201159294

Dependencies:   mbed

Committer:
el17oc
Date:
Sat May 30 06:12:09 2020 +0000
Revision:
2:ffbfd3f53ee2
Parent:
1:897160a1a3ae
Final Submission. I have read and agreed with Statement of Academic Integrity

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el17oc 1:897160a1a3ae 1 #include "snake.h"
el17oc 1:897160a1a3ae 2
el17oc 1:897160a1a3ae 3 Snake::Snake()
el17oc 1:897160a1a3ae 4 {
el17oc 1:897160a1a3ae 5
el17oc 1:897160a1a3ae 6 }
el17oc 1:897160a1a3ae 7
el17oc 1:897160a1a3ae 8 Snake::~Snake()
el17oc 1:897160a1a3ae 9 {
el17oc 2:ffbfd3f53ee2 10 }
el17oc 2:ffbfd3f53ee2 11
el17oc 2:ffbfd3f53ee2 12 void Snake::init()//int x, int y)
el17oc 2:ffbfd3f53ee2 13 {
el17oc 2:ffbfd3f53ee2 14 _x0 = 48; //initialises each part of the snake //_x0 and _y0 is the snake's head coordinate whose position is followed by the other bits periodically
el17oc 2:ffbfd3f53ee2 15 _x1 = 48;
el17oc 2:ffbfd3f53ee2 16 _x2 = 48;
el17oc 2:ffbfd3f53ee2 17 _x3 = 48;
el17oc 2:ffbfd3f53ee2 18 _x4 = 48;
el17oc 2:ffbfd3f53ee2 19 _x5 = 48;
el17oc 2:ffbfd3f53ee2 20
el17oc 2:ffbfd3f53ee2 21 _y0 = 20; //the snakes body is in a vertical positon
el17oc 2:ffbfd3f53ee2 22 _y1 = 19;
el17oc 2:ffbfd3f53ee2 23 _y2 = 18;
el17oc 2:ffbfd3f53ee2 24 _y3 = 17;
el17oc 2:ffbfd3f53ee2 25 _y4 = 16;
el17oc 2:ffbfd3f53ee2 26 _y5 = 15;
el17oc 2:ffbfd3f53ee2 27
el17oc 2:ffbfd3f53ee2 28 _apx = 48; //initial apple position - directly in front of snake
el17oc 2:ffbfd3f53ee2 29 _apy = 25;
el17oc 2:ffbfd3f53ee2 30 _gameover = false; //when _gameover = true, game cannot be played
el17oc 2:ffbfd3f53ee2 31 _reset_apple = false; //triggers the generation of a new apple position.
el17oc 2:ffbfd3f53ee2 32 _score = 0; //initialises score to 0
el17oc 2:ffbfd3f53ee2 33 _direction = down; //initial direction
el17oc 2:ffbfd3f53ee2 34 _countdown = 18; //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty
el17oc 2:ffbfd3f53ee2 35 }
el17oc 2:ffbfd3f53ee2 36
el17oc 2:ffbfd3f53ee2 37 Vector2D Snake::get_Snakehead()
el17oc 2:ffbfd3f53ee2 38 {
el17oc 2:ffbfd3f53ee2 39 Vector2D Snakehead; //defines Snakehead as a Vector
el17oc 2:ffbfd3f53ee2 40 Snakehead.x = _x0; //returns _x0, _y0 values
el17oc 2:ffbfd3f53ee2 41 Snakehead.y = _y0;
el17oc 2:ffbfd3f53ee2 42
el17oc 2:ffbfd3f53ee2 43 return Snakehead; //Snakehead position is called and used in GameEngine::get_LEDs by calling this class
el17oc 1:897160a1a3ae 44
el17oc 1:897160a1a3ae 45 }
el17oc 1:897160a1a3ae 46
el17oc 1:897160a1a3ae 47
el17oc 2:ffbfd3f53ee2 48 void Snake::apple_collected(N5110 &lcd, Gamepad &pad) //checks to see whether an apple has been collected
el17oc 1:897160a1a3ae 49 {
el17oc 1:897160a1a3ae 50
el17oc 2:ffbfd3f53ee2 51 if((_x0 == _apx) && (_y0 == _apy)) { // directly comparing position of the apple and the Snakehead by using an and statement to see if the x and y components are equal
el17oc 2:ffbfd3f53ee2 52 // if they are the same: the score increases, a new apple position is generated, the countdown timer is reset, LEDS and Speaker are triggered
el17oc 2:ffbfd3f53ee2 53 _score++; //increases score
el17oc 2:ffbfd3f53ee2 54 _reset_apple = true; //causes new apple position to be generated - _reset _apple is compared to a bool true - when an apple is collected a new apple position is generated
el17oc 2:ffbfd3f53ee2 55 _countdown = _countdown + 25; //38 is added to the current countdown timer - this larger _countdown is, the further the snake can travel to collect apples.
el17oc 2:ffbfd3f53ee2 56 pad.tone(1500.0,0.5); //if the counter is reset to just 38, there will be some distances the snake cannot as it is further than 38 pixels away - unless the player collects accumulates their available moves
el17oc 2:ffbfd3f53ee2 57 pad.led(2, 1); //toggles middle left led on
el17oc 2:ffbfd3f53ee2 58 pad.led(4, 1); //toggles middle right led on
el17oc 2:ffbfd3f53ee2 59 wait(0.1);
el17oc 2:ffbfd3f53ee2 60 pad.led(2, 0);
el17oc 2:ffbfd3f53ee2 61 pad.led(4, 0);
el17oc 1:897160a1a3ae 62
el17oc 2:ffbfd3f53ee2 63
el17oc 2:ffbfd3f53ee2 64
el17oc 2:ffbfd3f53ee2 65 } else {
el17oc 2:ffbfd3f53ee2 66 _countdown = _countdown - 1; //for each change in position, counter decreases by 1 - the counter represents how many moves you have to collect an apple
el17oc 2:ffbfd3f53ee2 67
el17oc 2:ffbfd3f53ee2 68 }
el17oc 2:ffbfd3f53ee2 69 }
el17oc 2:ffbfd3f53ee2 70
el17oc 2:ffbfd3f53ee2 71 int Snake::get_countdown()
el17oc 2:ffbfd3f53ee2 72 {
el17oc 2:ffbfd3f53ee2 73 //allows _countdown value to be called from other classes
el17oc 2:ffbfd3f53ee2 74 return _countdown;
el17oc 1:897160a1a3ae 75 }
el17oc 1:897160a1a3ae 76
el17oc 1:897160a1a3ae 77
el17oc 2:ffbfd3f53ee2 78 void Snake::check_gameover(N5110 &lcd)
el17oc 2:ffbfd3f53ee2 79 {
el17oc 2:ffbfd3f53ee2 80 if (_x0 == 15 ||_x0 == 69 || _y0 == 32 || _y0 == 0) { // the first condition is, if the snakehead coordinate touches the edge of the rectangle, it is gameover
el17oc 2:ffbfd3f53ee2 81 //the second condition for, game over = true, is if the snake head cooroinate is equal to one of the snake body bits coordinate
el17oc 2:ffbfd3f53ee2 82 _gameover = true; // the third conditios is game is over if the counter = 0, indicating you've ran out of moves.
el17oc 2:ffbfd3f53ee2 83 }
el17oc 2:ffbfd3f53ee2 84 if ((_x0 == _x1 && _y0 == _y1) || (_x0 == _x2 && _y0 == _x2) || (_x0 == _x2 && _y0 == _y2) || (_x0 == _x3 && _y0 == _y3) || (_x0 == _x4 && _y0 == _y4)|| (_x0 == _x5 && _y0 == _y5)|| (_x0 == _x6 && _y0 == _y6)|| (_x0 == _x7 && _y0 == _y7)) {
el17oc 2:ffbfd3f53ee2 85 _gameover = true;
el17oc 2:ffbfd3f53ee2 86 }
el17oc 2:ffbfd3f53ee2 87 if(_countdown == 0) {
el17oc 2:ffbfd3f53ee2 88 _gameover = true;
el17oc 1:897160a1a3ae 89
el17oc 2:ffbfd3f53ee2 90 }
el17oc 2:ffbfd3f53ee2 91 }
el17oc 2:ffbfd3f53ee2 92
el17oc 2:ffbfd3f53ee2 93 void Snake::render(N5110 &lcd, Gamepad &pad) //final function in the main function's while loop as the screen updates based on all any changes which occur in the functions
el17oc 1:897160a1a3ae 94 {
el17oc 2:ffbfd3f53ee2 95 lcd.clear(); //clears the lcd before assigning what is to be printed
el17oc 1:897160a1a3ae 96
el17oc 2:ffbfd3f53ee2 97 // plot the apple
el17oc 2:ffbfd3f53ee2 98 lcd.setPixel(_apx, _apy,1); //plot apple position -whether it is a new position or the same position
el17oc 2:ffbfd3f53ee2 99
el17oc 2:ffbfd3f53ee2 100 //plot the border
el17oc 2:ffbfd3f53ee2 101 lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT); //plots border of snake map
el17oc 2:ffbfd3f53ee2 102
el17oc 2:ffbfd3f53ee2 103 //plot the snake
el17oc 2:ffbfd3f53ee2 104 lcd.setPixel(_x0, _y0,1); //plots snake body's new position changed by move_snake() function
el17oc 2:ffbfd3f53ee2 105 lcd.setPixel(_x1, _y1,1);
el17oc 2:ffbfd3f53ee2 106 lcd.setPixel(_x2, _y2,1);
el17oc 2:ffbfd3f53ee2 107 lcd.setPixel(_x3, _y3,1);
el17oc 2:ffbfd3f53ee2 108 lcd.setPixel(_x4, _y4,1);
el17oc 2:ffbfd3f53ee2 109 lcd.setPixel(_x5, _y5,1);
el17oc 2:ffbfd3f53ee2 110 lcd.setPixel(_x6, _y6,1);
el17oc 2:ffbfd3f53ee2 111 lcd.setPixel(_x7, _y7,1); //new position of the end bit of the snake is plotted here
el17oc 2:ffbfd3f53ee2 112 // _x0, _y0 old positional values are cleared previously before this function in an earlier one as otherwise the program would lose reference of that pixel when the position updates and we wouldnt be able to clear it
el17oc 1:897160a1a3ae 113
el17oc 1:897160a1a3ae 114
el17oc 2:ffbfd3f53ee2 115 char buffer1[14];
el17oc 2:ffbfd3f53ee2 116 sprintf(buffer1," %2d %2d",_score, _countdown);
el17oc 2:ffbfd3f53ee2 117 lcd.printString(buffer1,0,5);
el17oc 2:ffbfd3f53ee2 118
el17oc 2:ffbfd3f53ee2 119 if (_gameover == true) { //As _gameover is a member variable, if the condition is the previous function is met, the true value will be stored in _gameover and can be accessed in this function
el17oc 2:ffbfd3f53ee2 120 lcd.clear(); //
el17oc 1:897160a1a3ae 121
el17oc 2:ffbfd3f53ee2 122 pad.led(1,1);
el17oc 2:ffbfd3f53ee2 123 pad.led(4,1);
el17oc 2:ffbfd3f53ee2 124 lcd.printString( " Game Over ", 0, 1 ); //prints game over message
el17oc 2:ffbfd3f53ee2 125 lcd.printString( " ~~~~~~~<:>-<", 0, 3 ); // prints symbolic snake
el17oc 2:ffbfd3f53ee2 126 char buffer1[14];
el17oc 2:ffbfd3f53ee2 127 sprintf(buffer1," Score: %2d", _score); //prints your score - cannot simply use N5110::printString as we need to output a value and the Number of inputs wouldnt match the function declaration
el17oc 2:ffbfd3f53ee2 128 lcd.printString(buffer1,0,4); ///print score
el17oc 1:897160a1a3ae 129
el17oc 1:897160a1a3ae 130
el17oc 1:897160a1a3ae 131 }
el17oc 1:897160a1a3ae 132
el17oc 2:ffbfd3f53ee2 133 // char buffer2[14];
el17oc 2:ffbfd3f53ee2 134 // sprintf(buffer2,"%2d",_score);
el17oc 2:ffbfd3f53ee2 135 // lcd.printString(buffer2,0,3);
el17oc 2:ffbfd3f53ee2 136
el17oc 2:ffbfd3f53ee2 137 lcd.refresh(); //updates the lcd display according to the code in this function
el17oc 2:ffbfd3f53ee2 138 }
el17oc 2:ffbfd3f53ee2 139
el17oc 2:ffbfd3f53ee2 140
el17oc 2:ffbfd3f53ee2 141
el17oc 2:ffbfd3f53ee2 142
el17oc 1:897160a1a3ae 143
el17oc 2:ffbfd3f53ee2 144 void Snake::get_direction(Gamepad &pad) //gets the direction based on the input of the gamepad
el17oc 2:ffbfd3f53ee2 145 {
el17oc 2:ffbfd3f53ee2 146 // int x; // int x was used as a variable to test whether the button were generating the correct output
el17oc 2:ffbfd3f53ee2 147 Directions direction = _direction; //"direction" stores the previous value of _direction to stop the snake going in the opposite direction to the way its travelling
el17oc 1:897160a1a3ae 148
el17oc 2:ffbfd3f53ee2 149 if(direction != left) { //if current direction is left, the not statement is false blocking access to the next command from the 'A' button preventing _direction being set to right
el17oc 2:ffbfd3f53ee2 150 if (pad.A_pressed()) {
el17oc 2:ffbfd3f53ee2 151
el17oc 2:ffbfd3f53ee2 152 _direction = right; //the snake direction is stored in _direction so on the next loop direction = right
el17oc 2:ffbfd3f53ee2 153 // x=1;
el17oc 2:ffbfd3f53ee2 154 }
el17oc 1:897160a1a3ae 155 }
el17oc 2:ffbfd3f53ee2 156 if(direction != right) {
el17oc 2:ffbfd3f53ee2 157 if (pad.Y_pressed()) {
el17oc 1:897160a1a3ae 158
el17oc 2:ffbfd3f53ee2 159 _direction = left;
el17oc 2:ffbfd3f53ee2 160 // x=2;
el17oc 2:ffbfd3f53ee2 161 }
el17oc 1:897160a1a3ae 162
el17oc 1:897160a1a3ae 163 }
el17oc 2:ffbfd3f53ee2 164 if(direction != up) {
el17oc 2:ffbfd3f53ee2 165 if (pad.B_pressed()) {
el17oc 2:ffbfd3f53ee2 166 // x=3;
el17oc 2:ffbfd3f53ee2 167 _direction = down;
el17oc 2:ffbfd3f53ee2 168 }
el17oc 2:ffbfd3f53ee2 169 }
el17oc 2:ffbfd3f53ee2 170 if(direction != down) {
el17oc 2:ffbfd3f53ee2 171 if (pad.X_pressed()) {
el17oc 1:897160a1a3ae 172
el17oc 2:ffbfd3f53ee2 173 _direction = up;
el17oc 2:ffbfd3f53ee2 174 // x=4;
el17oc 2:ffbfd3f53ee2 175 }
el17oc 2:ffbfd3f53ee2 176 } else {
el17oc 2:ffbfd3f53ee2 177 _direction = _direction; // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set
el17oc 1:897160a1a3ae 178
el17oc 1:897160a1a3ae 179 }
el17oc 2:ffbfd3f53ee2 180 // printf("direction %d ", x); //printf statements used in CoolTerm to check whether the input commands where working correctly
el17oc 1:897160a1a3ae 181 }
el17oc 1:897160a1a3ae 182
el17oc 1:897160a1a3ae 183
el17oc 2:ffbfd3f53ee2 184
el17oc 2:ffbfd3f53ee2 185 void Snake::move_snake() //assigns the new values of the snake position
el17oc 1:897160a1a3ae 186 {
el17oc 2:ffbfd3f53ee2 187 if (_direction == down) { //shifting the snake position bit by bit, with respect to _x0 and _y0;
el17oc 2:ffbfd3f53ee2 188 _x7 = _x6; //coordinate _x[i], _y[i] = _x[i-1], _y[i-1]
el17oc 2:ffbfd3f53ee2 189 _y7 = _y6;
el17oc 2:ffbfd3f53ee2 190 _x6 = _x5;
el17oc 2:ffbfd3f53ee2 191 _y6 = _y5;
el17oc 2:ffbfd3f53ee2 192 _x5 = _x4;
el17oc 2:ffbfd3f53ee2 193 _y5 = _y4;
el17oc 2:ffbfd3f53ee2 194 _x4 = _x3;
el17oc 2:ffbfd3f53ee2 195 _y4 = _y3;
el17oc 2:ffbfd3f53ee2 196 _x3 = _x2;
el17oc 2:ffbfd3f53ee2 197 _y3 = _y2;
el17oc 2:ffbfd3f53ee2 198 _x2 = _x1;
el17oc 2:ffbfd3f53ee2 199 _y2 = _y1;
el17oc 2:ffbfd3f53ee2 200 _x1 = _x0;
el17oc 2:ffbfd3f53ee2 201 _y1 = _y0; //_x1 ,_y1 and must be assingned to _x0,_y0 before its own position updates otherwise bit 0 and bit 1 would be plotted as 1 pixel
el17oc 1:897160a1a3ae 202
el17oc 2:ffbfd3f53ee2 203 _x0 = _x0;
el17oc 2:ffbfd3f53ee2 204 _y0 = _y0 + 1; //changes the position one bit at a time so the snake can only move horizontally or vertically
el17oc 2:ffbfd3f53ee2 205 }
el17oc 2:ffbfd3f53ee2 206 if (_direction == up) {
el17oc 2:ffbfd3f53ee2 207 _x7 = _x6;
el17oc 2:ffbfd3f53ee2 208 _y7 = _y6;
el17oc 2:ffbfd3f53ee2 209 _x6 = _x5;
el17oc 2:ffbfd3f53ee2 210 _y6 = _y5;
el17oc 2:ffbfd3f53ee2 211 _x5 = _x4;
el17oc 2:ffbfd3f53ee2 212 _y5 = _y4;
el17oc 2:ffbfd3f53ee2 213 _x4 = _x3;
el17oc 2:ffbfd3f53ee2 214 _y4 = _y3;
el17oc 2:ffbfd3f53ee2 215 _x3 = _x2;
el17oc 2:ffbfd3f53ee2 216 _y3 = _y2;
el17oc 2:ffbfd3f53ee2 217 _x2 = _x1;
el17oc 2:ffbfd3f53ee2 218 _y2 = _y1;
el17oc 2:ffbfd3f53ee2 219 _x1 = _x0;
el17oc 2:ffbfd3f53ee2 220 _y1 = _y0;
el17oc 1:897160a1a3ae 221
el17oc 2:ffbfd3f53ee2 222 _x0 = _x0; // x remains constant
el17oc 2:ffbfd3f53ee2 223 _y0 = _y0 - 1; //y decerases by 1 to move up as the y axis decreases from top to bottom
el17oc 1:897160a1a3ae 224
el17oc 1:897160a1a3ae 225 }
el17oc 2:ffbfd3f53ee2 226 if (_direction == left) {
el17oc 2:ffbfd3f53ee2 227 _x7 = _x6;
el17oc 2:ffbfd3f53ee2 228 _y7 = _y6;
el17oc 2:ffbfd3f53ee2 229 _x6 = _x5;
el17oc 2:ffbfd3f53ee2 230 _y6 = _y5;
el17oc 2:ffbfd3f53ee2 231 _x5 = _x4;
el17oc 2:ffbfd3f53ee2 232 _y5 = _y4;
el17oc 2:ffbfd3f53ee2 233 _x4 = _x3;
el17oc 2:ffbfd3f53ee2 234 _y4 = _y3;
el17oc 2:ffbfd3f53ee2 235 _x3 = _x2;
el17oc 2:ffbfd3f53ee2 236 _y3 = _y2;
el17oc 2:ffbfd3f53ee2 237 _x2 = _x1;
el17oc 2:ffbfd3f53ee2 238 _y2 = _y1;
el17oc 2:ffbfd3f53ee2 239 _x1 = _x0;
el17oc 2:ffbfd3f53ee2 240 _y1 = _y0;
el17oc 2:ffbfd3f53ee2 241
el17oc 2:ffbfd3f53ee2 242 _x0 = _x0 - 1; //changes x=x-1
el17oc 2:ffbfd3f53ee2 243 _y0 = _y0; //y remains the same to move left
el17oc 1:897160a1a3ae 244
el17oc 1:897160a1a3ae 245
el17oc 1:897160a1a3ae 246
el17oc 1:897160a1a3ae 247 }
el17oc 1:897160a1a3ae 248
el17oc 2:ffbfd3f53ee2 249 if (_direction == right) {
el17oc 2:ffbfd3f53ee2 250 _x7 = _x6;
el17oc 2:ffbfd3f53ee2 251 _y7 = _y6;
el17oc 2:ffbfd3f53ee2 252 _x6 = _x5;
el17oc 2:ffbfd3f53ee2 253 _y6 = _y5;
el17oc 2:ffbfd3f53ee2 254 _x5 = _x4;
el17oc 2:ffbfd3f53ee2 255 _y5 = _y4;
el17oc 2:ffbfd3f53ee2 256 _x4 = _x3;
el17oc 2:ffbfd3f53ee2 257 _y4 = _y3;
el17oc 2:ffbfd3f53ee2 258 _x3 = _x2;
el17oc 2:ffbfd3f53ee2 259 _y3 = _y2;
el17oc 2:ffbfd3f53ee2 260 _x2 = _x1;
el17oc 2:ffbfd3f53ee2 261 _y2 = _y1;
el17oc 2:ffbfd3f53ee2 262 _x1 = _x0;
el17oc 2:ffbfd3f53ee2 263 _y1 = _y0;
el17oc 2:ffbfd3f53ee2 264
el17oc 2:ffbfd3f53ee2 265 _x0 = _x0 + 1;
el17oc 2:ffbfd3f53ee2 266 _y0 = _y0;
el17oc 1:897160a1a3ae 267
el17oc 1:897160a1a3ae 268
el17oc 1:897160a1a3ae 269 }
el17oc 1:897160a1a3ae 270 }
el17oc 1:897160a1a3ae 271
el17oc 1:897160a1a3ae 272
el17oc 2:ffbfd3f53ee2 273 void Snake::render_clear_tail(N5110 &lcd)
el17oc 1:897160a1a3ae 274 {
el17oc 1:897160a1a3ae 275
el17oc 2:ffbfd3f53ee2 276 lcd.setPixel(_x7, _y7, false); //sets the end pixel to 0. it must be set to 0 before its position updates otherwise the snakebody will grow continually from _x7, _y7 coordinate
el17oc 1:897160a1a3ae 277 }
el17oc 1:897160a1a3ae 278
el17oc 2:ffbfd3f53ee2 279 bool Snake::get_gameover() //methods to access member variables of the class
el17oc 1:897160a1a3ae 280 {
el17oc 2:ffbfd3f53ee2 281 return _gameover;
el17oc 2:ffbfd3f53ee2 282 }
el17oc 2:ffbfd3f53ee2 283 int Snake::get_score()
el17oc 2:ffbfd3f53ee2 284 {
el17oc 2:ffbfd3f53ee2 285 return _score;
el17oc 1:897160a1a3ae 286 }
el17oc 1:897160a1a3ae 287
el17oc 1:897160a1a3ae 288
el17oc 2:ffbfd3f53ee2 289
el17oc 2:ffbfd3f53ee2 290
el17oc 2:ffbfd3f53ee2 291
el17oc 2:ffbfd3f53ee2 292 void Snake::get_Apple_position(N5110 &lcd)
el17oc 2:ffbfd3f53ee2 293 {
el17oc 2:ffbfd3f53ee2 294 if(_reset_apple == true) { // _reset_apple is a triggered when an apple is collected and causes a new Apple position to be randomly generated
el17oc 2:ffbfd3f53ee2 295 _reset_apple = false; // returned to false immediately so another position can be generated function can be triggered again in the next loop
el17oc 2:ffbfd3f53ee2 296 lcd.setPixel(_apx, _apy,0); //sets the exisiting apple position to 0 to remove it from lcd.
el17oc 2:ffbfd3f53ee2 297 _apx = rand()%52+16; //54 = width of the rectangle on the lcd. - the x value of the apple has a range of 52 so it cannot spawn in either side of the wall
el17oc 2:ffbfd3f53ee2 298 _apy = rand()%28+2; // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69
el17oc 2:ffbfd3f53ee2 299 }
el17oc 2:ffbfd3f53ee2 300
el17oc 2:ffbfd3f53ee2 301
el17oc 2:ffbfd3f53ee2 302 }
el17oc 2:ffbfd3f53ee2 303
el17oc 1:897160a1a3ae 304