level.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <draw.h>
  5. #include "mahjongg.h"
  6. void
  7. consumeline(Biobuf *b)
  8. {
  9. while(Bgetc(b) != '\n')
  10. ;
  11. }
  12. /* parse a level file */
  13. int
  14. parse(char *layout)
  15. {
  16. int x = 0, y = 0, depth = 0;
  17. char c;
  18. Biobuf *b;
  19. b = Bopen(layout, OREAD);
  20. if(b == nil) {
  21. fprint(2, "could not open file %s: %r\n", layout);
  22. return 0;
  23. }
  24. level.remaining = 0;
  25. while((c = Bgetc(b)) > 0) {
  26. switch(c) {
  27. case '\n':
  28. x = 0;
  29. y = (y+1) % Ly;
  30. if(!y)
  31. depth++;
  32. break;
  33. case '.':
  34. orig.board[depth][x][y].which = 0;
  35. x++;
  36. break;
  37. case '1':
  38. orig.remaining++;
  39. case '2':
  40. case '3':
  41. case '4':
  42. orig.board[depth][x++][y].which = c-48;
  43. break;
  44. default:
  45. consumeline(b);
  46. break;
  47. }
  48. }
  49. Bterm(b);
  50. return 1;
  51. }
  52. int
  53. indextype(int type)
  54. {
  55. int t;
  56. if(type < 108)
  57. t = (type/36)*Facey * 9 + ((type%36)/4)*Facex;
  58. else if(type < 112)
  59. t = Seasons;
  60. else if(type < 128)
  61. t = 3*Facey + (((type+12)%36)/4)*Facex;
  62. else if(type < 132)
  63. t = Flowers;
  64. else
  65. t = 4*Facey + (((type+28)%36)/4)*Facex;
  66. return t;
  67. }
  68. Point
  69. indexpt(int type)
  70. {
  71. Point p;
  72. /*
  73. * the first 108 bricks are 4 of each, 36 per line:
  74. * x = (index%36)/4
  75. * y = (index)/36
  76. * then multiply by the size of a single tile.
  77. * the next 4 are the seasons, so x = index%4...
  78. * and so on...
  79. */
  80. if(type < 108)
  81. p = Pt(((type%36)/4)*Facex, (type/36)*Facey);
  82. else if(type < 112)
  83. p = Pt((type%4)*Facex, 3*Facey);
  84. else if(type < 128)
  85. p = Pt((((type+12)%36)/4)*Facex, 3*Facey);
  86. else if(type < 132)
  87. p = Pt(((type+4)%4)*Facex, 4*Facey);
  88. else
  89. p = Pt((((type+28)%36)/4)*Facex, 4*Facey);
  90. return p;
  91. }
  92. /* use the seed to generate a replayable game */
  93. void
  94. generate(uint seed)
  95. {
  96. int x, y, d, n;
  97. int order[144];
  98. Point p;
  99. srand(seed);
  100. for (x = 0; x < Tiles; x++)
  101. order[x] = x;
  102. for(x = 0; x < Tiles; x++) {
  103. n = order[x];
  104. y = nrand(Tiles);
  105. order[x] = order[y];
  106. order[y] = n;
  107. }
  108. n = 0;
  109. for(d = 0; d < Depth; d++)
  110. for(y = 0; y < Ly; y++)
  111. for(x = 0; x < Lx; x++)
  112. if(orig.board[d][x][y].which == 1) {
  113. orig.board[d][x][y].type = indextype(order[n]);
  114. p = indexpt(order[n++]);
  115. orig.board[d][x][y].start = p;
  116. orig.board[d][x+1][y].start = p;
  117. orig.board[d][x][y+1].start = p;
  118. orig.board[d][x+1][y+1].start = p;
  119. }
  120. if(n != orig.remaining)
  121. fprint(2, "level improperly generated: %d elements, "
  122. "should have %d\n", n, orig.remaining);
  123. orig.c = NC;
  124. orig.l = NC;
  125. orig.done = 0;
  126. level = orig;
  127. }