1 /** 2 * Copyright: © 2012-2014 Anton Gushcha 3 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 4 * Authors: NCrashed <ncrashed@gmail.com>, 5 * LeMarwin <lemarwin42@gmail.com>, 6 * Nazgull09 <nazgull90@gmail.com> 7 */ 8 module ant.world; 9 10 import devol.world; 11 import ant.progtype; 12 import ant.operators; 13 import core.thread; 14 import core.time; 15 16 import std.random; 17 import std.stdio; 18 import std.process; 19 import ant.app; 20 21 import derelict.sdl2.sdl; 22 23 class AntWorld: WorldAbstract 24 { 25 void initialize() 26 { 27 zeros(); 28 generateMap(); 29 print(); 30 } 31 static immutable int size = 18; 32 static int Food=25; 33 34 const bool[size][size] getMap() 35 { 36 return map; 37 } 38 39 private: 40 41 bool[size][size] map; 42 43 public: 44 45 46 bool checkForFood(int x, int y) 47 { 48 if (x>=size || y>=size) return false; 49 50 return map[x][y]; 51 } 52 void removeFood(int x, int y) 53 { 54 map[x][y]=false; 55 } 56 57 void generateMap() 58 { 59 writeln("Generating map"); 60 Ant Grower = new Ant; 61 62 Grower.x = size/2+uniform!"[]"(-1,1); 63 Grower.y = size/2+uniform!"[]"(-1,1); 64 65 Grower.Direction = cast(Ant.Faces)uniform!"[]"(cast(uint)Ant.Faces.min, cast(uint)Ant.Faces.max); 66 67 int FC = 1; 68 int breakCount = 0; 69 70 writeln("Adding delegate"); 71 Grower.addCheat(delegate bool () 72 { 73 final switch(Grower.Direction) 74 { 75 case Grower.Faces.NORTH: 76 if(Grower.y>=2) 77 return checkForFood(Grower.x,Grower.y-2)||checkForFood(Grower.x,Grower.y-1) 78 ||checkForFood(Grower.x-1,Grower.y-2)||checkForFood(Grower.x-1,Grower.y-1) 79 ||checkForFood(Grower.x+1,Grower.y-2)||checkForFood(Grower.x+1,Grower.y-1); 80 break; 81 case Grower.Faces.SOUTH: 82 if(Grower.y<=size-2) 83 return checkForFood(Grower.x,Grower.y+2)||checkForFood(Grower.x,Grower.y+1) 84 ||checkForFood(Grower.x-1,Grower.y+2)||checkForFood(Grower.x-1,Grower.y+1) 85 ||checkForFood(Grower.x+1,Grower.y+2)||checkForFood(Grower.x+1,Grower.y+1); 86 break; 87 case Grower.Faces.EAST: 88 if(Grower.x<=size-2) 89 return checkForFood(Grower.x+2,Grower.y)||checkForFood(Grower.x+1,Grower.y) 90 ||checkForFood(Grower.x+2,Grower.y-1)||checkForFood(Grower.x+1,Grower.y-1) 91 ||checkForFood(Grower.x+2,Grower.y+1)||checkForFood(Grower.x+1,Grower.y+1); 92 break; 93 case Grower.Faces.WEST: 94 if(Grower.x>=2) 95 return checkForFood(Grower.x-2,Grower.y)||checkForFood(Grower.x-1,Grower.y) 96 ||checkForFood(Grower.x-2,Grower.y-1)||checkForFood(Grower.x-1,Grower.y-1) 97 ||checkForFood(Grower.x-2,Grower.y+1)||checkForFood(Grower.x-1,Grower.y+1); 98 break; 99 } 100 return false; 101 }); 102 writeln("Placing food"); 103 auto flag = true; 104 while(FC!=Food && breakCount < 100) 105 { 106 writeln("FC = ", FC); 107 writeln("Food = ", Food); 108 int c = uniform!"[]"(0,1); 109 GoForward F = new GoForward; 110 TurnLeft L = new TurnLeft; 111 TurnRight R = new TurnRight; 112 writeln("Choosing direction"); 113 if(c&&!Grower.MyCheat()) 114 { 115 writeln("Forward"); 116 F.apply(Grower, null, this); 117 118 int d = uniform!"[]"(0,1); 119 writeln("Chance to place food: ", d); 120 if ( Grower.x >= 1 && Grower.y >= 1 && Grower.x <= size-1 && Grower.y <= size - 1 ) 121 { 122 if((d||flag)&&!map[Grower.x][Grower.y]) 123 { 124 writeln("Placing food"); 125 map[Grower.x][Grower.y] = true; 126 FC++; 127 flag = false; 128 } 129 else 130 { 131 flag = true; 132 } 133 } 134 } 135 else 136 { 137 writeln("Rotating"); 138 breakCount++; 139 int d = uniform!"[]"(0,1); 140 if(d) 141 { 142 writeln("Left"); 143 L.apply(Grower, null, this); 144 } 145 else 146 { 147 writeln("Right"); 148 R.apply(Grower,null,this); 149 } 150 } 151 152 153 154 void printGr() 155 { 156 writeln("Getting singleton"); 157 auto app = App.getSingleton(); 158 assert(app !is null); 159 160 app.clear(); 161 draw(app, app.food, app.empty, app.wall); 162 app.draw(app.ants[Grower.Direction], 32u*(Grower.x+1), 32u*(Grower.y+1), 32u, 32u); 163 app.present(); 164 } 165 166 printGr(); 167 } 168 } 169 void zeros() 170 { 171 foreach(ref line; map) 172 { 173 foreach(ref cell; line) 174 { 175 cell = false; 176 } 177 } 178 } 179 180 void print() 181 { 182 version(linux) 183 { 184 system("clear"); 185 } 186 foreach( l; map ) 187 { 188 foreach( c; l) 189 { 190 if (c) 191 write("x"); 192 else 193 write("-"); 194 } 195 writeln(); 196 } 197 } 198 199 void draw(App app, SDL_Texture* food, SDL_Texture* empty, SDL_Texture* wall) 200 { 201 assert(food !is null); 202 assert(empty !is null); 203 204 foreach(uint j, l; map ) 205 { 206 foreach(uint i, c; l) 207 { 208 if (c) 209 { 210 //writeln("drawing food at ", (j+1)*32u, " ", (i+1)*32u); 211 app.draw(food, (j+1)*32u , (i+1)*32u, 32u, 32u); 212 } 213 else 214 { 215 //writeln("drawing empty at ", (j+1)*32u, " ", (i+1)*32u); 216 app.draw(empty, (j+1)*32u , (i+1)*32u, 32u, 32u); 217 } 218 } 219 } 220 221 foreach(uint i; 0..map.length+2) 222 app.draw(wall, i*32u, 0, 32u, 32u); 223 foreach(uint i; 0..map.length+2) 224 app.draw(wall, i*32u, (cast(uint)map.length+1)*32u, 32u, 32u); 225 foreach(uint i; 0..map.length+2) 226 app.draw(wall, 0, i*32u, 32u, 32u); 227 foreach(uint i; 0..map.length+2) 228 app.draw(wall, (cast(uint)map.length+1)*32u, i*32u, 32u, 32u); 229 } 230 231 } 232