Zamiel

boirlg_bot.linq

Sep 4th, 2018
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.83 KB | None | 0 0
  1. <Query Kind="Program">
  2. <Reference>&lt;RuntimeDirectory&gt;\System.Drawing.dll</Reference>
  3. <Namespace>System.Drawing</Namespace>
  4. </Query>
  5.  
  6. void Main()
  7. {
  8. var roomDescs = new RoomsProvider();
  9. roomDescs.Load(@"C:\Users\Admin\Documents\isaac\levelgen\resources\rooms");
  10.  
  11. var bot1Total = new int[14];
  12. var bot2Total = new int[14];
  13. foreach (var fp in new DirectoryInfo(@"C:\Users\Admin\Documents\isaac\levelgen\dump2").GetFiles())
  14. {
  15. using (var file = File.OpenRead(fp.FullName))
  16. {
  17. Console.WriteLine(file.Name);
  18. var reader = new LayoutReader(file, roomDescs);
  19. StageBlock sb;
  20. while ((sb = reader.Read()) != null)
  21. {
  22. for (var i = 0; i < sb.Stages.Length; i++)
  23. {
  24. if (sb.Stages[i].StageId == 9 || sb.Stages[i].StageId == 12 || (sb.Stages[i].StageId == 10 && sb.Stages[i].StageType == 1) || (sb.Stages[i].StageId == 11 && sb.Stages[i].StageType == 1))
  25. continue;
  26. var seedStr = SeedToString(sb.Seed);
  27. //Console.WriteLine("{0} (Stage {1})", SeedToString(sb.Seed), sb.Stages[i].StageId);
  28. //Console.WriteLine("--------");
  29. Func<Room, string> roomToChar = (room) =>
  30. {
  31. if (room == null)
  32. return "O";
  33. if (room.StageIndex == 0 && room.RoomType == RoomType.ROOM_DEFAULT && room.RoomId == 2)
  34. return "S";
  35. if (room.RoomType == RoomType.ROOM_BOSS)
  36. return "B";
  37. return "X";
  38. };
  39. for (var y = 0; y < 13; y++)
  40. {
  41.  
  42. var line = string.Join("", Enumerable.Range(0, 13).Select(k => roomToChar(sb.Stages[i].RoomGrid[y][k])));
  43. //Console.WriteLine(line);
  44. }
  45.  
  46. var bot = new Bot1();
  47. bot.Start(sb.Stages[i]);
  48. do
  49. {
  50. } while (bot.Think());
  51. var bot2 = new Bot2();
  52. bot2.Start(sb.Stages[i]);
  53. do
  54. {
  55. } while (bot2.Think());
  56. //Console.WriteLine(bot.RoomsVisited);
  57. //Console.WriteLine(bot2.RoomsVisited);
  58. bot1Total[sb.Stages[i].StageId] += bot.RoomsVisited;
  59. bot2Total[sb.Stages[i].StageId] += bot2.RoomsVisited;
  60. }
  61. }
  62. }
  63. }
  64. bot1Total.Dump();
  65. bot2Total.Dump();
  66. }
  67.  
  68. public class RoomState
  69. {
  70. public bool Visited = false;
  71. public bool Revealed = false;
  72. public Room Room;
  73. }
  74. public class BotState
  75. {
  76. public Stage Stage;
  77. public Point Pos;
  78. public RoomState[][] GridState;
  79. public Room CurrentRoom { get { return GridState[Pos.Y][Pos.X].Room; }}
  80. public BotState(Stage stage)
  81. {
  82. Stage = stage;
  83. GridState = new RoomState[13][];
  84. for (var j = 0; j < GridState.Length; j++)
  85. GridState[j] = new RoomState[13];
  86.  
  87. var gridStateArr = new RoomState[Stage.Rooms.Length];
  88. for (var y = 0; y < 13; y++)
  89. {
  90. for (var x = 0; x < 13; x++)
  91. {
  92. var room = stage.RoomGrid[y][x];
  93. if (room == null)
  94. {
  95. GridState[y][x] = new RoomState();
  96. continue;
  97. }
  98.  
  99. var state = gridStateArr[room.RoomOffset] ?? new RoomState { Room = room};
  100. gridStateArr[room.RoomOffset] = state;
  101. GridState[y][x] = state;
  102. }
  103. }
  104. }
  105. }
  106. public abstract class Bot
  107. {
  108. public BotState State;
  109. public Room[][] Grid { get { return State.Stage.RoomGrid; } }
  110. public RoomState[][] GridState { get { return State.GridState; } }
  111.  
  112. public Point GetStart()
  113. {
  114. for (var y = 0; y < 13; y++)
  115. {
  116. for (var x = 0; x < 13; x++)
  117. {
  118. var room = Grid[y][x];
  119. if (room == null)
  120. continue;
  121. if (room.StageIndex == 0 && room.RoomType == RoomType.ROOM_DEFAULT && room.RoomId == 2 //Standard start room
  122. || ((room.StageIndex == 16 || room.StageIndex == 17) && room.RoomType == RoomType.ROOM_DEFAULT && room.RoomId == 0)) //Chest/DarkRoom start rooms
  123. {
  124. return new Point(x, y);
  125. }
  126. }
  127. }
  128. throw new Exception("Start room not found D:");
  129. }
  130. public Point GetEnd()
  131. {
  132. for (var y = 0; y < 13; y++)
  133. {
  134. for (var x = 0; x < 13; x++)
  135. {
  136. var room = Grid[y][x];
  137. if (room == null)
  138. continue;
  139. if (room.RoomType == RoomType.ROOM_BOSS)
  140. {
  141. return new Point(x, y);
  142. }
  143. }
  144. }
  145. throw new Exception("Boss room not found D:");
  146. }
  147.  
  148. public virtual void Start(Stage stage)
  149. {
  150. State = new BotState(stage);
  151. State.Pos = GetStart();
  152. }
  153. public abstract bool Think();
  154. public virtual void End()
  155. {
  156. }
  157.  
  158. public static bool InBounds(Point p)
  159. {
  160. return p.X >= 0 && p.Y >= 0 && p.X < 13 && p.Y < 13;
  161. }
  162.  
  163. //The points are using the top/left most grid x/y.
  164. #region shape doors
  165. public static Dictionary<RoomShape, Point[]> ShapeDoors = new Dictionary<UserQuery.RoomShape, System.Drawing.Point[]>
  166. {
  167. // U R D L, U R D L
  168. {RoomShape.ROOMSHAPE_1x1, new [] { new Point(0, -1), new Point(1, 0), new Point(0, 1), new Point(-1, 0), default(Point), default(Point), default(Point), default(Point) } },
  169. {RoomShape.ROOMSHAPE_1x2, new [] { new Point(0, -1), new Point(1, 0), new Point(0, 2), new Point(-1, 0), default(Point), new Point(1, 1), default(Point), new Point(-1, 1) } },
  170. {RoomShape.ROOMSHAPE_2x1, new [] { new Point(0, -1), new Point(2, 0), new Point(0, 1), new Point(-1, 0), new Point(1, -1), default(Point), new Point(1, 1), default(Point) } },
  171. {RoomShape.ROOMSHAPE_2x2, new [] { new Point(0, -1), new Point(2, 0), new Point(0, 2), new Point(-1, 0), new Point(1, -1), new Point(2, 1), new Point(1, 2), new Point(-1, 1)} },
  172. {RoomShape.ROOMSHAPE_IH, new [] { default(Point), new Point(1, 0), default(Point), new Point(-1, 0) , default(Point), default(Point), default(Point), default(Point) } },
  173. {RoomShape.ROOMSHAPE_IIH, new [] { default(Point), new Point(2, 0), default(Point), new Point(-1, 0) , default(Point), default(Point), default(Point), default(Point) } },
  174. {RoomShape.ROOMSHAPE_IV, new [] { new Point(0, -1), default(Point), new Point(0, 1), default(Point), default(Point), default(Point), default(Point), default(Point) } },
  175. {RoomShape.ROOMSHAPE_IIV, new [] { new Point(0, -1), default(Point), new Point(0, 2), default(Point), default(Point), default(Point), default(Point), default(Point) } },
  176. {RoomShape.ROOMSHAPE_LTL, new [] { new Point(-1, 0), new Point(1, 0), new Point(-1, 2), new Point(-1, 0), new Point(0, -1), new Point(1, 1), new Point(0, 2), new Point(-2, 1) } },
  177. {RoomShape.ROOMSHAPE_LTR, new [] { new Point(0, -1), new Point(1, 0), new Point(0, 2), new Point(-1, 0), new Point(1, 0), new Point(2, 1), new Point(1, 2), new Point(-1, 1) } },
  178. {RoomShape.ROOMSHAPE_LBL, new [] { new Point(0, -1), new Point(2, 0), new Point(0, 1), new Point(-1, 0), new Point(1, -1), new Point(2, 1), new Point(1, 2), new Point(0,-1) } },
  179. {RoomShape.ROOMSHAPE_LBR, new [] { new Point(0, -1), new Point(2, 0), new Point(0, 2), new Point(-1, 0), new Point(1, -1), new Point(1, 1), new Point(1, 1), new Point(-1, 1) } },
  180. };
  181. #endregion
  182. }
  183.  
  184. public class Bot1 : Bot
  185. {
  186. Stack<Point> Visited = new Stack<System.Drawing.Point>();
  187. public int RoomsVisited;
  188.  
  189.  
  190. static RoomState[] exitRooms = new RoomState[8];
  191. #region weights
  192. static Dictionary<RoomShape, float> ShapeWeights = new Dictionary<UserQuery.RoomShape, float>
  193. {
  194. {RoomShape.ROOMSHAPE_1x1, 1},
  195. {RoomShape.ROOMSHAPE_1x2, 1.5f},
  196. {RoomShape.ROOMSHAPE_2x1, 1.5f},
  197. {RoomShape.ROOMSHAPE_2x2, 2},
  198. {RoomShape.ROOMSHAPE_IH, 1f},
  199. {RoomShape.ROOMSHAPE_IIH, 1.5f},
  200. {RoomShape.ROOMSHAPE_IIV, 1.5f},
  201. {RoomShape.ROOMSHAPE_IV, 1f},
  202. {RoomShape.ROOMSHAPE_LBL, 1.75f},
  203. {RoomShape.ROOMSHAPE_LBR, 1.75f},
  204. {RoomShape.ROOMSHAPE_LTL, 1.75f},
  205. {RoomShape.ROOMSHAPE_LTR, 1.75f},
  206. };
  207. #endregion
  208.  
  209. void RevealRooms()
  210. {
  211. //Revealing secret rooms is fine for now since we don't actually enter them.
  212. GridState[State.Pos.Y][State.Pos.X].Revealed = true;
  213. var exits = ShapeDoors[State.CurrentRoom.Shape];
  214. for (var i = 0; i < exits.Length; i++)
  215. {
  216. if (exits[i] == default(Point))
  217. continue;
  218.  
  219. var dstP = State.Pos.Add(exits[i]);
  220. if (!InBounds(dstP))
  221. continue;
  222.  
  223. var dstRoom = State.GridState[dstP.Y][dstP.X];
  224. dstRoom.Revealed = true;
  225. }
  226. }
  227. bool IsPossible(Point pos, HashSet<Point> visited)
  228. {
  229. var room = State.GridState[pos.Y][pos.X];
  230. if (!room.Revealed)
  231. return true;
  232. if (room.Revealed && room.Room == null)
  233. return false;
  234.  
  235. visited.Add(pos);
  236.  
  237. var exits = ShapeDoors[room.Room.Shape];
  238. for (var i = 0; i < exits.Length; i++)
  239. {
  240. if (exits[i] == default(Point))
  241. continue;
  242.  
  243. var dstP = State.Pos.Add(exits[i]);
  244. if (!InBounds(dstP))
  245. continue;
  246.  
  247. if (visited.Contains(dstP))
  248. continue;
  249.  
  250. var dstRoom = State.GridState[dstP.Y][dstP.X];
  251. if (dstRoom.Revealed && dstRoom.Room != null && !IsPossible(dstP, visited))
  252. return false;
  253. }
  254. return true;
  255. }
  256.  
  257. Point ChooseNextRoom()
  258. {
  259. var exits = ShapeDoors[State.CurrentRoom.Shape];
  260. for (var i = 0; i < exits.Length; i++)
  261. {
  262. exitRooms[i] = null;
  263. if (exits[i] == default(Point))
  264. continue;
  265.  
  266. var dstP = State.Pos.Add(exits[i]);
  267. if (!InBounds(dstP))
  268. continue;
  269.  
  270. var dstRoom = State.GridState[dstP.Y][dstP.X];
  271. if (dstRoom.Visited || dstRoom.Room == null)
  272. continue;
  273.  
  274. if (dstRoom.Room.RoomType == RoomType.ROOM_BOSS)
  275. return dstP;
  276.  
  277. if (dstRoom.Room.RoomType != RoomType.ROOM_DEFAULT)
  278. continue;
  279.  
  280. if (!IsPossible(dstP, new HashSet<Point>()))
  281. {
  282. Func<RoomState, string> roomToChar = (room) =>
  283. {
  284. if (room == null || room.Room == null)
  285. return "O";
  286. return room.Visited ? "1" : "2";
  287. };
  288. for (var y = 0; y < 13; y++)
  289. {
  290.  
  291. var line = string.Join("", Enumerable.Range(0, 13).Select(k => roomToChar(this.GridState[y][k])));
  292. Console.WriteLine(line);
  293. }
  294. IsPossible(dstP, new HashSet<Point>());
  295. continue;
  296. }
  297.  
  298. exitRooms[i] = dstRoom;
  299. }
  300.  
  301. Array.Sort(exitRooms, (l, r) =>
  302. {
  303. if (l == null && r != null)
  304. return 1;
  305. if (r == null && l != null)
  306. return -1;
  307. if (l == null && r == null)
  308. return 0;
  309. return ShapeWeights[l.Room.Shape].CompareTo(ShapeWeights[r.Room.Shape]);
  310. });
  311.  
  312. return exitRooms[0] != null && exitRooms[0].Room != null ? new Point(exitRooms[0].Room.RoomX, exitRooms[0].Room.RoomY) : new Point(-1,-1);
  313. }
  314.  
  315. public override bool Think()
  316. {
  317. GridState[State.Pos.Y][State.Pos.X].Visited = true;
  318. RevealRooms();
  319.  
  320. var nextRoomPos = ChooseNextRoom();
  321. if (nextRoomPos.X == -1 && nextRoomPos.Y == -1)
  322. {
  323. if (Visited.Count < 1)
  324. {
  325. Func<RoomState, string> roomToChar = (room) =>
  326. {
  327. if (room == null || room.Room == null)
  328. return "O";
  329. return room.Visited ? "1" : "2";
  330. };
  331. for (var y = 0; y < 13; y++)
  332. {
  333.  
  334. var line = string.Join("", Enumerable.Range(0, 13).Select(k => roomToChar(this.GridState[y][k])));
  335. Console.WriteLine(line);
  336. }
  337. throw new Exception("Ran out of choices before finding the boss room");
  338. }
  339. State.Pos = Visited.Pop();
  340. return true;
  341. }
  342.  
  343. RoomsVisited++;
  344. var nextRoom = Grid[nextRoomPos.Y][nextRoomPos.X];
  345. var adjNextRoomPos = new Point(nextRoom.RoomX, nextRoom.RoomY);
  346. Visited.Push(State.Pos);
  347. State.Pos = adjNextRoomPos;
  348.  
  349. if (State.CurrentRoom.RoomType == RoomType.ROOM_BOSS)
  350. return false;
  351. return true;
  352. }
  353. }
  354. public class Bot2 : Bot
  355. {
  356. Stack<Point> Visited = new Stack<System.Drawing.Point>();
  357. public int RoomsVisited;
  358.  
  359.  
  360. static RoomState[] exitRooms = new RoomState[8];
  361. #region weights
  362. static Dictionary<RoomShape, float> ShapeWeights = new Dictionary<UserQuery.RoomShape, float>
  363. {
  364. {RoomShape.ROOMSHAPE_1x1, 1},
  365. {RoomShape.ROOMSHAPE_1x2, 1.5f},
  366. {RoomShape.ROOMSHAPE_2x1, 1.5f},
  367. {RoomShape.ROOMSHAPE_2x2, 2},
  368. {RoomShape.ROOMSHAPE_IH, 1f},
  369. {RoomShape.ROOMSHAPE_IIH, 1.5f},
  370. {RoomShape.ROOMSHAPE_IIV, 1.5f},
  371. {RoomShape.ROOMSHAPE_IV, 1f},
  372. {RoomShape.ROOMSHAPE_LBL, 1.75f},
  373. {RoomShape.ROOMSHAPE_LBR, 1.75f},
  374. {RoomShape.ROOMSHAPE_LTL, 1.75f},
  375. {RoomShape.ROOMSHAPE_LTR, 1.75f},
  376. };
  377. #endregion
  378. Point ChooseNextRoom()
  379. {
  380. var exits = ShapeDoors[State.CurrentRoom.Shape];
  381. for (var i = 0; i < exits.Length; i++)
  382. {
  383. exitRooms[i] = null;
  384. if (exits[i] == default(Point))
  385. continue;
  386.  
  387. var dstP = State.Pos.Add(exits[i]);
  388. if (!InBounds(dstP))
  389. continue;
  390.  
  391. var dstRoom = State.GridState[dstP.Y][dstP.X];
  392. if (dstRoom.Visited || dstRoom.Room == null)
  393. continue;
  394.  
  395. if (dstRoom.Room.RoomType != RoomType.ROOM_DEFAULT && dstRoom.Room.RoomType != RoomType.ROOM_BOSS)
  396. continue;
  397.  
  398. exitRooms[i] = dstRoom;
  399. }
  400.  
  401. Array.Sort(exitRooms, (l, r) =>
  402. {
  403. if (l == null && r != null)
  404. return 1;
  405. if (r == null && l != null)
  406. return -1;
  407. if (l == null && r == null)
  408. return 0;
  409. if (l.Room == null && r.Room != null)
  410. return 1;
  411. if (r.Room == null && l.Room != null)
  412. return -1;
  413. return -ShapeWeights[l.Room.Shape].CompareTo(ShapeWeights[r.Room.Shape]);
  414. });
  415.  
  416. return exitRooms[0] != null && exitRooms[0].Room != null ? new Point(exitRooms[0].Room.RoomX, exitRooms[0].Room.RoomY) : new Point(-1, -1);
  417. }
  418.  
  419. public override bool Think()
  420. {
  421. GridState[State.Pos.Y][State.Pos.X].Visited = true;
  422.  
  423. var nextRoomPos = ChooseNextRoom();
  424. if (nextRoomPos.X == -1 && nextRoomPos.Y == -1)
  425. {
  426. if (Visited.Count < 1)
  427. throw new Exception("Ran out of choices before finding the boss room");
  428. State.Pos = Visited.Pop();
  429. return true;
  430. }
  431.  
  432. RoomsVisited++;
  433. var nextRoom = Grid[nextRoomPos.Y][nextRoomPos.X];
  434. var adjNextRoomPos = new Point(nextRoom.RoomX, nextRoom.RoomY);
  435. Visited.Push(State.Pos);
  436. State.Pos = adjNextRoomPos;
  437.  
  438. if (State.CurrentRoom.RoomType == RoomType.ROOM_BOSS)
  439. return false;
  440. return true;
  441. }
  442. }
  443. public static class PointExt
  444. {
  445. public static Point Add(this Point l, Point r)
  446. {
  447. return new Point(l.X+r.X, l.Y + r.Y);
  448. }
  449. }
  450.  
  451. public class RoomDescriptor
  452. {
  453. public RoomType RoomType;
  454. public int RoomId; //variant
  455. public int RoomSubType;
  456. public RoomShape RoomShape;
  457. }
  458. public class RoomsProvider
  459. {
  460. public Dictionary<int, Dictionary<Tuple<RoomType, int>, RoomDescriptor>> StageRooms;
  461. public void Load(string path)
  462. {
  463. var xmlFiles = new DirectoryInfo(path).GetFiles("*.xml");
  464. StageRooms = new Dictionary<int, Dictionary<Tuple<RoomType, int>, RoomDescriptor>>();
  465. for (var i = 0; i < xmlFiles.Length; i++)
  466. {
  467. var stageIdx = int.Parse(Regex.Match(xmlFiles[i].Name, "^(\\d\\d)").Groups[1].Value);
  468. var doc = XDocument.Load(xmlFiles[i].FullName);
  469. var xmlRooms = doc.XPathSelectElements("//rooms/room").ToList();
  470.  
  471. var rooms = new Dictionary<Tuple<RoomType, int>, RoomDescriptor>();
  472. for (var j = 0; j < xmlRooms.Count; j++)
  473. {
  474. var id = xmlRooms[j].Get<int>("variant");
  475. var type = (RoomType)xmlRooms[j].Get<int>("type");
  476. rooms[Tuple.Create(type, id)] = new RoomDescriptor
  477. {
  478. RoomType = type,
  479. RoomId = id,
  480. RoomSubType = xmlRooms[j].Get<int>("subtype"),
  481. RoomShape = (RoomShape)xmlRooms[j].Get<int>("shape")
  482. };
  483. }
  484. StageRooms[stageIdx] = rooms;
  485. }
  486.  
  487. StageRooms[3] = StageRooms[1];
  488. StageRooms[6] = StageRooms[4];
  489. StageRooms[9] = StageRooms[7];
  490. StageRooms[12] = StageRooms[10];
  491. }
  492. }
  493.  
  494. public class LayoutReader
  495. {
  496. Stream stream;
  497. RoomsProvider RoomsProv;
  498. public LayoutReader(Stream s, RoomsProvider roomsProv)
  499. {
  500. stream = s;
  501. RoomsProv = roomsProv;
  502. }
  503.  
  504. public StageBlock Read()
  505. {
  506. if (stream.Position >= stream.Length)
  507. return null;
  508. var stages = new Stage[14];
  509. var seed = stream.ReadUInt32();
  510. for (var i = 0; i < 14; i++)
  511. {
  512. var stageId = stream.ReadInt8();
  513. var stageType = stream.ReadInt8();
  514. var roomCount = stream.ReadInt8();
  515. var gridCount = stream.ReadInt8();
  516. var grid = new Room[13][];
  517. for (var j = 0; j < grid.Length; j++)
  518. grid[j] = new Room[13];
  519.  
  520. var seedStr = SeedToString(seed);
  521.  
  522. var rooms = new Room[roomCount];
  523. for (var j = 0; j < gridCount; j++)
  524. {
  525. var sRoom = Room.ReadRoom(stream, RoomsProv);
  526. var room = rooms[sRoom.RoomOffset] ?? sRoom; //Have all of the grid parts of a room point to the same reference.
  527.  
  528. grid[sRoom.RoomY][sRoom.RoomX] = room;
  529. rooms[room.RoomOffset] = room;
  530. }
  531.  
  532. var iAmEror = Room.ReadNonGridRoom(stream, RoomsProv);
  533. var crawlSpace = Room.ReadNonGridRoom(stream, RoomsProv);
  534. var blackMarket = Room.ReadNonGridRoom(stream, RoomsProv);
  535. Room bossRush = null;
  536. if (stageId == 6)
  537. bossRush = Room.ReadNonGridRoom(stream, RoomsProv);
  538.  
  539. stages[i] = new Stage(stageId, stageType, grid, rooms);
  540. }
  541. return new StageBlock { Seed = seed, Stages = stages };
  542. }
  543.  
  544. }
  545.  
  546. public class Room
  547. {
  548. public int StageIndex;
  549. public int RoomOffset;
  550. public int RoomX;
  551. public int RoomY;
  552. public RoomType RoomType;
  553. public int RoomSubType;
  554. public int RoomId;
  555. public RoomShape Shape;
  556. public static Room ReadRoom(Stream s, RoomsProvider prov)
  557. {
  558. var r = new Room
  559. {
  560. RoomOffset = s.ReadInt8(),
  561. RoomX = s.ReadInt8(),
  562. RoomY = s.ReadInt8(),
  563. StageIndex = s.ReadInt8(),
  564. RoomType = (RoomType)s.ReadInt8(),
  565. RoomSubType = s.ReadInt8(),
  566. RoomId = s.ReadInt16(),
  567. };
  568. r.Shape = prov.StageRooms[r.StageIndex][Tuple.Create(r.RoomType, r.RoomId)].RoomShape;
  569. return r;
  570. }
  571. public static Room ReadNonGridRoom(Stream s, RoomsProvider prov)
  572. {
  573. var r = new Room
  574. {
  575. RoomOffset = -1,
  576. RoomX = -1,
  577. RoomY = -1,
  578. StageIndex = s.ReadInt8(),
  579. RoomType = (RoomType)s.ReadInt8(),
  580. RoomSubType = s.ReadInt8(),
  581. RoomId = s.ReadInt16(),
  582. };
  583. r.Shape = prov.StageRooms[r.StageIndex][Tuple.Create(r.RoomType, r.RoomId)].RoomShape;
  584. return r;
  585. }
  586. }
  587.  
  588. public enum FloorType
  589. {
  590. Special = 0,
  591. Basement = 1,
  592. Cellar = 2,
  593. BurningBasement = 3,
  594. Caves = 4,
  595. Catacombs = 5,
  596. FloodedCaves = 6,
  597. Depths = 7,
  598. Necropolis = 8,
  599. DankDepths = 9,
  600. Womb = 10,
  601. Utero = 11,
  602. ScarredWomb = 12,
  603. BlueWomb = 13,
  604. Sheol = 14,
  605. Cathedral = 15,
  606. DarkRoom = 16,
  607. Chest = 17,
  608. }
  609.  
  610.  
  611. public enum RoomType
  612. {
  613. ROOM_NULL = 0,
  614. ROOM_DEFAULT = 1,
  615. ROOM_SHOP = 2,
  616. ROOM_ERROR = 3,
  617. ROOM_TREASURE = 4,
  618. ROOM_BOSS = 5,
  619. ROOM_MINIBOSS = 6,
  620. ROOM_SECRET = 7,
  621. ROOM_SUPERSECRET = 8,
  622. ROOM_ARCADE = 9,
  623. ROOM_CURSE = 10,
  624. ROOM_CHALLENGE = 11,
  625. ROOM_LIBRARY = 12,
  626. ROOM_SACRIFICE = 13,
  627. ROOM_DEVIL = 14,
  628. ROOM_ANGEL = 15,
  629. ROOM_DUNGEON = 16,
  630. ROOM_BOSSRUSH = 17,
  631. ROOM_ISAACS = 18,
  632. ROOM_BARREN = 19,
  633. ROOM_CHEST = 20,
  634. ROOM_DICE = 21,
  635. ROOM_BLACK_MARKET = 22,
  636. ROOM_GREED_EXIT = 23,
  637. NUM_ROOMTYPES = 24
  638. }
  639.  
  640. public enum RoomShape
  641. {
  642. ROOMSHAPE_NULL = 0,
  643. ROOMSHAPE_1x1 = 1,
  644. ROOMSHAPE_IH = 2,
  645. ROOMSHAPE_IV = 3,
  646. ROOMSHAPE_1x2 = 4,
  647. ROOMSHAPE_IIV = 5,
  648. ROOMSHAPE_2x1 = 6,
  649. ROOMSHAPE_IIH = 7,
  650. ROOMSHAPE_2x2 = 8,
  651. ROOMSHAPE_LTL = 9,
  652. ROOMSHAPE_LTR = 10,
  653. ROOMSHAPE_LBL = 11,
  654. ROOMSHAPE_LBR = 12,
  655. NUM_ROOMSHAPES = 13
  656. }
  657.  
  658. public class Stage
  659. {
  660. public int StageId;
  661. public int StageType;
  662. public Room[][] RoomGrid;
  663. public Room[] Rooms;
  664.  
  665. public Stage(int stageId, int stageType, Room[][] grid, Room[] rooms)
  666. {
  667. StageId = stageId;
  668. StageType = stageType;
  669. RoomGrid = grid;
  670. Rooms = rooms;
  671. }
  672. }
  673.  
  674. public class StageBlock
  675. {
  676. public uint Seed;
  677. public Stage[] Stages;
  678. }
  679.  
  680. enum Direction : int
  681. {
  682. None = 0,
  683. North = 1,
  684. East = 2,
  685. South = 4,
  686. West = 8,
  687. NorthEast = North | East,
  688. NorthWest = North | West,
  689. SouthEast = South | East,
  690. SouthWest = South | West,
  691. }
  692.  
  693. // Define other methods and classes here
  694. static string SeedToString(uint num)
  695. {
  696. const string chars = "ABCDEFGHJKLMNPQRSTWXYZ01234V6789";
  697. byte x = 0;
  698. var tnum = num;
  699. while (tnum != 0)
  700. {
  701. x += ((byte)tnum);
  702. x += (byte)(x + (x >> 7));
  703. tnum >>= 5;
  704. }
  705. num ^= 0x0FEF7FFD;
  706. tnum = (num) << 8 | x;
  707.  
  708. var ret = new char[8];
  709. for (int i = 0; i < 6; i++)
  710. {
  711. ret[i] = chars[(int)(num >> (27 - (i * 5)) & 0x1F)];
  712. }
  713. ret[6] = chars[(int)(tnum >> 5 & 0x1F)];
  714. ret[7] = chars[(int)(tnum & 0x1F)];
  715.  
  716. return new string(ret);
  717. }
  718.  
  719. class Rng
  720. {
  721. public uint seed;
  722. public int shift1;
  723. public int shift2;
  724. public int shift3;
  725. public uint next()
  726. {
  727. var num = seed;
  728. num ^= num >> shift1;
  729. num ^= num << shift2;
  730. num ^= num >> shift3;
  731. seed = num;
  732. return num;
  733. }
  734. };
Advertisement
Add Comment
Please, Sign In to add comment