Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: experimental/hex/hex_maniac.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/hex/hex_instance.cc ('k') | experimental/hex/index.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 #include "hex_instance.h"
3
4 #include <ctype.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #include <iostream>
9 using std::cout;
10 using std::cin;
11 using std::endl;
12
13
14 namespace hexgame {
15
16 // Hex Maniac v1.2
17 // Copyright Cameron Browne
18 // 5/10/2000
19 //
20 // Point-pairing algorithm with blind row.
21 //
22 // Feel free to experiment with and develop this code, but please
23 // acknowledge its contribution to any derived work.
24 //
25 // Compiles with the Microsoft C/C++ compiler (12.00.8168) and linker
26 // (6.00.8168) but should be portable. Use the following options:
27 // cl -GX hex_12.cpp
28 //
29 // Guaranteed bug free. Any errors must have been introduced by
30 // subsequent developers :)
31 //
32 // From: http://www.cameronius.com/games/hex/hex_12.cpp
33 // which is part of http://www.cameronius.com/games/hex/
34 //
35
36
37 //////////////////////////////////////////////////////////////////////////////
38
39 const int MIN_N = 3; // Smallest board size
40 const int MAX_N = 26; // Largest board size (limit of alphanumeric notatio n)
41
42 enum State // board point or move state
43 {
44 EMPTY = 0, // empty board position
45 VERT = 1, // computer player (vertical = j)
46 HORZ = 2, // human player (horizontal = i)
47 NUM_STATES
48 };
49
50 static const char* StateNames[NUM_STATES] =
51 {
52 "Empty",
53 "Vertical",
54 "Horizontal",
55 };
56
57 struct Coord
58 {
59 Coord(int i_=-1, int j_=-1) : i(i_), j(j_) {}
60
61 int i;
62 int j;
63 };
64
65 // Hexagonal neighbours of X:
66 // >-<
67 // >-< 0 >-< | 5 | 0
68 // < 5 >-< 1 > ---+---+---
69 // >-< X >-< == 4 | X | 1
70 // < 4 >-< 2 > ---+---+---
71 // >-< 3 >-< 3 | 2 |
72 // >-<
73 static const Coord nbor[6] =
74 {
75 Coord(1,-1), Coord(1,0), Coord(0,1),
76 Coord(-1,1), Coord(-1,0), Coord(0,-1)
77 };
78
79 void ConvertColRowToHexManiac(int column, int row, int *hex_i, int *hex_j);
80 void ConvertHexManiacToColRow(int hex_i, int hex_j, int* column, int* row);
81
82 // Blind row defense templates
83 //
84 // Key:
85 // h = existing HORZ piece
86 // v = existing VERT piece
87 // . = empty position
88 // x = existing piece (VERT or HORZ)
89 // - = don't care
90 // H = last HORZ move
91 // V = VERT's best reply
92 // r = reentrant block on furthest connected piece (or adjacent if none)
93 //
94 // Note: more general situations should go last.
95 //
96 const int NUM_DEFENSE_TEMPLATES = 25;
97 static const char* HEX_DefenseTemplate[NUM_DEFENSE_TEMPLATES][2] =
98 {
99 { "H V - -", "- - - -" }, // acute blind corner
100 { "- - . H", "- - V -" }, // obtuse blind corner
101 { "- V H v", "- - - -" },
102 { "- v H V", "- - - -" },
103 { "- V H .", "h . . h" },
104 { "- . H V", "h . . h" },
105 { "v h H -", "V . h -" },
106 { "- H h v", "h . V -" },
107 { "- V H -", "h . h -" },
108 { "- - H V", "- h . h" },
109 { "- V H -", "- v - -" },
110 { "- H V -", "- v - -" },
111 { "- V H -", "- - h -" },
112 { "- H V -", "h - - -" },
113 { ". H h -", "V - - -" },
114 { "- h H .", "- - V -" },
115 { "- V H -", "h . - -" },
116 { "- H V -", "- . h -" },
117 { "- h H h", "- v V v" },
118 { "- h H h", "v V v -" },
119 { "- h H v", "- v V -" },
120 { "- v H h", "- V v -" },
121 { "- H r -", "h - - -" },
122 { "- r H -", "- - h -" },
123 { "- . H .", "- V . -" }, // reentrant block below (general case)
124 };
125
126
127 ///////////////////////////////////////////////////////////////////////////////
128
129 class HEX_Game
130 {
131 public:
132 HEX_Game(int n_=11) : N(n_), SwapOption(false) {} // HACKED SwapOption
133 ~HEX_Game() {}
134
135 bool Play(void);
136 void SetInstance(HexGameInstance *instance) { instance_ = instance; }
137 private:
138 bool DoMove(State who);
139 bool GetUserMove(Coord& move) const;
140 bool GameWon(State who);
141 bool GameWon(State who, Coord const& from);
142 void RandomEmptyPosition(Coord& posn) const;
143 void ShowBoard(void) const;
144 bool IsValid(Coord const& posn) const;
145
146 void BestOpening(Coord& move) const;
147 bool GoodSwap(Coord const& move) const;
148 bool BestComputerMove(Coord& move) const;
149 bool DefendBlindRow(Coord& move) const;
150 void SpareMove(Coord& move) const;
151
152 void DoUpdate() const;
153 private:
154 State Board[MAX_N][MAX_N]; // the board
155 int N; // current board size NxN
156 int NumMoves; // number of moves played
157 Coord Last; // opponent's last move
158 bool SwapOption; // whether the swap option is enabled
159 bool HasSwapped; // whether a player has swapped already
160 State WhoStarted; // who played first
161 bool Visit[MAX_N][MAX_N]; // for rough working
162
163 HexGameInstance* instance_;
164 };
165
166
167 ///////////////////////////////////////////////////////////////////////////////
168
169
170 void HEX_Game::DoUpdate() const {
171 pp::Core* core = pp::Module::Get()->core();
172 if(!core)
173 return;
174 printf("Got computer move, calling CallOnMainThread!\n");
175 core->CallOnMainThread(0 /*no delay*/, pp::CompletionCallback(
176 UpdateCallback, instance_));
177 }
178
179
180 // Alternates moves between players until the game is won
181 //
182 // Returns: whether user choose to continue playing
183 //
184 bool HEX_Game::Play(void)
185 {
186 memset(Board, 0, sizeof(Board));
187 NumMoves = 0;
188 HasSwapped = false;
189
190 // Determine who starts
191 cout << "\nDo you want to start? [y/n/q]: ";
192 char ch('n');
193
194 /// cin >> ch;
195 ch = 'y'; /// HACK -- allow user to start
196
197 if (tolower(ch) == 'q')
198 exit(1);
199
200 WhoStarted = (tolower(ch) == 'y') ? HORZ : VERT;
201
202 if (WhoStarted == HORZ)
203 ShowBoard();
204
205 // Play a game
206 State who(WhoStarted);
207 while (!DoMove(who)) {
208 who = State((NumMoves + WhoStarted + 1) % 2 + 1);
209 }
210
211 cout << "\nGame won by " << StateNames[who] << "!" << endl;
212 cout << "\nPlay again on " << N << 'x' << N << "? [y/n]: ";
213 cin >> ch;
214
215 if (who == VERT)
216 instance_->SetComputerWins();
217 else
218 instance_->SetUserWins();
219
220 DoUpdate();
221
222 return (tolower(ch) == 'y');
223 }
224
225 // Determines and plays a move for the specfied player
226 //
227 // Returns: whether this move wins the game
228 //
229 bool HEX_Game::DoMove(State who)
230 {
231 Coord move;
232 bool did_swap = (who==HORZ) ? GetUserMove(move) : BestComputerMove(move) ;
233 if (did_swap)
234 {
235 // 'who' chose to swap
236 State opp = (who == VERT) ? HORZ : VERT;
237 Board[Last.j][Last.i] = EMPTY; // undo opening move
238 Board[Last.i][Last.j] = who; // redo its reflection
239 ShowBoard();
240 cout << endl << "Swap! " << StateNames[who][0] << " takes ";
241 cout << char('A' + Last.j) << 1 + Last.i << "." << endl;
242
243 WhoStarted = who;
244 HasSwapped = true;
245 }
246 else
247 {
248 // Make the move
249 Board[move.j][move.i] = who;
250 NumMoves++;
251 Last = move;
252
253 // Show the result
254 ShowBoard();
255 cout << endl << StateNames[who][0] << " plays at ";
256 cout << char('A' + move.i) << 1 + move.j << "." << endl;
257 }
258
259 return GameWon(who);
260 }
261
262 // Reads user's move from the keyboard (HORZ)
263 //
264 // Returns: whether user chose to swap
265 //
266 // We call WaitForUserMove, which gets the user move from a queue (or waits
267 // for a new entry in the queue) in order to synchronize with the GUI.
268 // The indicated move could either be a replaces the cin code to get 'i/j'.
269 // Currently, we don't provide swap as an option.
270 // NOTE: We send an update (message) just once to indicate the game loop is
271 // ready, so that the UI knows it can now send user moves.
272 //
273 bool HEX_Game::GetUserMove(Coord& move) const
274 {
275 static bool gameInitialized = false;
276 if (!gameInitialized) {
277 // we need to send a message to the UI just once that we have
278 // reached this code -- which indicates that not only is the nexe
279 // loaded but that the game loop is ready for events to be queued.
280 instance_->SetGameLoopReady();
281 DoUpdate();
282 gameInitialized = true;
283 }
284 // char str[4];
285 if (SwapOption && !HasSwapped && NumMoves==1)
286 {
287 char ch('y');
288 cout << endl << "Swap opening move? ";
289 if (GoodSwap(Last))
290 cout << "(I would) [y/n/q]: ";
291 else
292 cout << "(I wouldn't) [y/n/q]: ";
293 cin >> ch;
294
295 if (tolower(ch) == 'q')
296 exit(2);
297
298 if (tolower(ch) == 'y')
299 return true; // Swap
300 }
301
302 do {
303 cout << endl << "Enter move [eg f6/q]: ";
304 cout << "Waiting for UI to send move...";
305 // cin >> str;
306
307 // if (str[0] == 'q')
308 // exit(3);
309 uint32_t column, row;
310 instance_->WaitForUserMove(&column, &row);
311 ConvertColRowToHexManiac(column, row, &move.i, &move.j);
312 printf("MOVE IS %d:%d\n", move.i, move.j);
313 //move.i = tolower(str[0]) - 'a';
314 //move.j = atoi(&str[1]) - 1;
315 if (!IsValid(move)) {
316 cout << "MOVE " << move.i << ":" << move.j << " is NOT valid" << endl;
317 instance_->SetInvalidMove();
318 DoUpdate();
319 } else {
320 cout << "MOVE " << move.i << ":" << move.j << " is valid" << e ndl;
321 instance_->SetValidMove();
322 }
323 if (Board[move.j][move.i]) {
324 printf("Board non-empty contents for %d:%d are %d\n", move.i, move.j, Board[move.j][move.i]);
325 } else {
326 printf("Board empty contents for %d:%d are %d\n", move.i, move .j, Board[move.j][move.i]);
327 }
328 } while (!IsValid(move) || Board[move.j][move.i]);
329
330 return false;
331 }
332
333 // Returns: whether the game has been won by the specified player
334 //
335 bool HEX_Game::GameWon(State who)
336 {
337 fprintf(stderr, "Entered GameWon\n");
338 memset(Visit, 0, sizeof(Visit));
339 if (who == VERT)
340 {
341 for (int i = 0; i < N; i++)
342 if (Board[0][i]==VERT && !Visit[0][i] && GameWon(VERT, C oord(i,0)))
343 return true;
344 }
345 else
346 {
347 for (int j = 0; j < N; j++)
348 if (Board[j][0]==HORZ && !Visit[j][0] && GameWon(HORZ, C oord(0,j)))
349 return true;
350 }
351 fprintf(stderr, "Exited GameWon\n");
352 return false;
353 }
354
355 // Recursively examines neighbours of potential winning chains
356 //
357 // Returns: whether the game has been won by the specified player
358 //
359 bool HEX_Game::GameWon(State who, Coord const& from)
360 {
361 if ((who==HORZ && from.i==N-1) || (who==VERT && from.j==N-1))
362 return true;
363
364 Visit[from.j][from.i] = true; // this coord has been visited
365
366 for (int n = 0; n < 6; n++)
367 {
368 // Check neighbours for continuation of chain
369 Coord to(from.i + nbor[n].i, from.j + nbor[n].j);
370 if
371 (
372 IsValid(to) && Board[to.j][to.i]==who
373 &&
374 !Visit[to.j][to.i] && GameWon(who, to)
375 )
376 return true;
377 }
378 return false;
379 }
380
381 // Draws board in ASCII text format
382 //
383 void HEX_Game::ShowBoard(void) const
384 {
385 // Show alphabetical (HORZ) labels
386 cout << endl << " ";
387 for (int i = 0; i < N; i++)
388 cout << char('A' + i) << ' ';
389 cout << endl;
390
391 for (int j = 0; j < N; j++)
392 {
393 // Show numeric (VERT) labels
394 for (int s = 0; s < j; s++)
395 cout << ' ';
396 if (j < 9)
397 cout << ' ';
398 cout << j + 1;
399
400 // Show state of each board position along this row
401 for (int i = 0; i < N; i++)
402 if (Board[j][i] == VERT)
403 cout << " V";
404 else if (Board[j][i] == HORZ)
405 cout << " H";
406 else
407 cout << " .";
408 cout << endl;
409 }
410 }
411
412 // Returns: whether posn is within the bounds of the board
413 //
414 bool
415 HEX_Game::IsValid(Coord const& posn) const
416 {
417 return (posn.i >= 0 && posn.i < N && posn.j >= 0 && posn.j < N);
418 }
419
420
421 ///////////////////////////////////////////////////////////////////////////////
422 // Strategic operations
423
424 // Determines computer's best opening move (VERT)
425 //
426 void HEX_Game::BestOpening(Coord& move) const
427 {
428 move = Coord(N - 1, 0); // obtuse corner in blind row
429 }
430
431 // Returns: whether this opening move is worth swapping
432 //
433 bool
434 HEX_Game::GoodSwap(Coord const& move) const
435 {
436 return (move.i == N - move.j - 1); // swap along short diag onal
437 }
438
439 // Determines best move for computer (VERT)
440 //
441 // Returns: true on swap, else false
442 //
443 bool
444 HEX_Game::BestComputerMove(Coord& move) const
445 {
446 if (NumMoves == 0)
447 {
448 BestOpening(move); // opening move
449 }
450 else if (NumMoves == 1 && SwapOption && !HasSwapped && GoodSwap(Last))
451 {
452 return true; // swap opponent 's opening move
453 }
454 else if (Last.j == 0)
455 {
456 DefendBlindRow(move); // defend the blind row
457 }
458 else
459 {
460 if (Last.i < N - Last.j) // determine dual point on left
461 move = Coord(N - Last.j, N - Last.i - 1);
462 else // deter mine dual point on right
463 move = Coord(N - Last.j - 1, N - Last.i);
464 }
465
466 if (!IsValid(move) || Board[move.j][move.i])
467 SpareMove(move); // spare move - do some damage!
468
469
470 int ui_column, ui_row;
471 ConvertHexManiacToColRow(move.i, move.j, &ui_column, &ui_row);
472 // UPDATE COMPUTER'S MOVE
473 instance_->SetComputerMove(ui_column, ui_row);
474 DoUpdate();
475
476 return false;
477 }
478
479 // Determines best move along the blind row (row 0)
480 //
481 // Returns:
482 // Whether appropriate defending move was found.
483 //
484 bool HEX_Game::DefendBlindRow(Coord& move) const
485 {
486 move = Coord(-1, -1); // should already be initialised but mak e sure
487
488 for (int d = 0; d < NUM_DEFENSE_TEMPLATES; d++)
489 {
490 // Find root position H on top row
491 int root;
492 for (root = 0; root < 4; root++)
493 if (HEX_DefenseTemplate[d][0][root * 2] == 'H')
494 break;
495 if
496 (
497 (root>=4) // no ro ot found
498 ||
499 (root==0 && !(Last.i==0 && Last.j==0)) // acute corner no good
500 ||
501 (root==3 && !(Last.i==N-1 && Last.j==0)) // obtus e corner no good
502 )
503 continue;
504
505 // Check whether rest of template matches board position
506 bool valid = true;
507
508 int reentrant = 0;
509
510 for (int j = 0; j < 2 && valid; j++)
511 for (int c = 0; c < 4 && valid; c++)
512 {
513 int i = Last.i - root + c;
514 char ch = HEX_DefenseTemplate[d][j][c * 2];
515
516 if (ch == 'V' && !Board[j][i])
517 move = Coord(i, j);
518 else if (ch == 'V' && Board[j][i])
519 valid = false;
520 else if (ch == 'h' && Board[j][i] != HORZ)
521 valid = false;
522 else if (ch == 'v' && Board[j][i] != VERT)
523 valid = false;
524 else if (ch == 'x' && !Board[j][i])
525 valid = false;
526 else if (ch == '.' && Board[j][i])
527 valid = false;
528 else if (ch == 'r')
529 {
530 if (Board[j][i] == VERT)
531 valid = false;
532 else
533 {
534 move = Coord(Last);
535 reentrant = (i < root) ? -1 : 1; // is reentrant move
536 }
537 }
538 }
539
540 if (!valid)
541 continue; // invalid template
542
543 if (move.i == -1 || move.j == -1)
544 continue; // no valid reply found
545
546 if (reentrant)
547 {
548 if (reentrant > 0)
549 {
550 // Find reentrant block above
551 while (move.i < N - 1)
552 {
553 if (!Board[0][move.i])
554 return true; // adjacent block above
555
556 if (!Board[1][move.i])
557 {
558 move = Coord(move.i, 1);
559 return true; // reentrant block above
560 }
561 move.i++;
562 }
563 }
564 else
565 {
566 // Find reentrant block below
567 while (move.i >= 0)
568 {
569 if (!Board[0][move.i])
570 return true; // adjacent block above
571
572 if (!Board[1][move.i - 1])
573 {
574 move = Coord(move.i - 1, 1);
575 return true; // reentrant block above
576 }
577 move.i--;
578 }
579 }
580 return false; // no reentrant block found
581 }
582 return true; // good move found!
583 }
584 return false;
585 }
586
587
588 // Determines best spare move. There will ALWAYS be a spare move somewhere.
589 //
590 void HEX_Game::SpareMove(Coord& move) const
591 {
592 // Look for urgent moves on the blind row
593 move.j = 0;
594 for (move.i = 0; move.i < N; move.i++)
595 if
596 (
597 !Board[0][move.i]
598 &&
599 (
600 (move.i < N - 1 && Board[0][move.i + 1] == HORZ )
601 &&
602 (
603 (Board[1][move.i] == VERT )
604 ||
605 (move.i > 0 && !Board[1][move.i] && Boar d[1][move.i-1]==HORZ)
606 )
607 ||
608 (move.i > 0 && Board[0][move.i - 1] == HORZ
609 &&
610 (
611 (Board[1][move.i - 1] == VERT )
612 ||
613 (!Board[1][move.i] && Board[1][move.i + 1] == HORZ )
614 ))
615 )
616 )
617 return;
618
619 // If top obtuse corner is empty, take it
620 if (!Board[0][N - 1])
621 {
622 move = Coord(N - 1, 0);
623 return;
624 }
625
626 // Block any reentrant point on row 1
627 move.j = 1;
628 for (move.i = 0; move.i < N - 1; move.i++) // skip move.i = = N - 1
629 if
630 (
631 !Board[1][move.i]
632 &&
633 (
634 (Board[0][move.i] == HORZ && Board[0][move.i + 1 ] != HORZ )
635 ||
636 (Board[0][move.i + 1] == HORZ && Board[0][move.i ] != HORZ)
637 )
638 )
639 return;
640
641 // Block any point adjacent to White on row 0
642 move.j = 0;
643 for (move.i = 0; move.i < N; move.i++)
644 if
645 (
646 !Board[0][move.i]
647 &&
648 (
649 (move.i > 0 && Board[0][move.i - 1] == HORZ )
650 ||
651 (move.i < N - 1 && Board[0][move.i + 1] == HORZ)
652 )
653 )
654 return;
655
656 // Take any point an empty point away from Black on row 0
657 move.j = 0;
658 for (move.i = 0; move.i < N; move.i++)
659 if
660 (
661 !Board[0][move.i]
662 &&
663 (
664 (move.i > 1 && !Board[0][move.i-1] && Board[0][m ove.i-2]==VERT )
665 ||
666 (move.i < N-2 && !Board[0][move.i+1] && Board[0] [move.i+2]==VERT )
667 )
668 )
669 return;
670
671 // Take any empty point from top obtuse corner down (must be at least on e)
672 for (move.j = 0; move.j < N; move.j++)
673 for (move.i = N-1; move.i >= 0; move.i--)
674 if (!Board[move.j][move.i])
675 return;
676
677 move = Coord(-1, -1); // bad result
678 }
679
680
681 ///////////////////////////////////////////////////////////////////////////////
682
683 void* AppMain(void* param)
684 {
685 HexGameInstance* pepper_instance = static_cast<HexGameInstance*>(param);
686 cout << "Hex Maniac v1.2" << endl;
687 cout << "Cameron Browne 5/10/2000" << endl << endl;
688 cout << "You are horizontal (H), computer is vertical (V)" << endl;
689
690 int n = 11;
691 /*
692 if (argc == 2)
693 {
694 n = atoi(argv[1]);
695 if (n < MIN_N)
696 n = MIN_N;
697 else if (n > MAX_N)
698 n = MAX_N;
699 }
700 */
701 HEX_Game game(n);
702 game.SetInstance(pepper_instance);
703 while (game.Play());
704 return 0;
705 }
706
707
708
709
710 // Move from JS is based on 'straight' columns that are 1-based
711 // 4:1
712 // 2:1 3:1 4:2
713 // 1:1 2:2 3:2 4:3
714 // 3:3 4:4
715 //
716 // while the i/j are based on 0-based grid that looks like:
717 // . . . . . . . . . . .
718 // . . . . . . . . . . .
719 // . . . . . . . . . . .
720 // . . . . . . . . . . .
721 // . . . . . . . . . . .
722 // . . . . . . . . . . .
723 // . . . . . . . . . . .
724 //
725 // where i is how many columns from the left we are (0-based) in this
726 // 'shifted' view
727 //
728 // Here's another view with the numbers from UI col:row shown
729 //
730 // 1:1 2:1 3:1 4:1 5:1 6:1
731 // 2:2 3:2 4:2 5:2
732 // 3:3 4:3 5:3
733 //
734 // Top 1:1->0:0 2:1->1:0 3:1->2:0 4:1->3:0
735 // Next 2:2->0:1 3:2->1:1 4:2->2:1
736 // 3:3->0:2 4:3->1:3
737 //
738 // Need to handle the case where the rhombus is shrinking -- column > 11
739 // TODO (make sure this can be expanded to handle different sizes)
740 // Note that when column > 11, column is always > row
741 // 12:1 -> 10:1
742 // 13:1 -> 10:2
743 // 14:1 -> 10:3
744 //
745 // 13:1 -> 10:2
746 // 13:2 -> 9:3
747 // 13:3 -> 8:4
748 //
749 // col:row x:y col-11 - row
750 // 14:1 -> 10:3 3
751 // 14:2 -> 9:4 3
752 // 14:3 -> 8:5 3
753 //
754 // 15:1 -> 10:4
755 // 16:1 -> 10:5
756 // 21:1 -> 10:10
757 // 19:3 -> 8:10
758 //
759 void ConvertColRowToHexManiac(int column, int row, int *hex_i, int *hex_j) {
760 if (column < 12) { // FIXME -- magic number (12)
761 *hex_i = column - row;
762 *hex_j = row -1;
763 } else {
764 *hex_j = (column-11) + (row - 1);
765 *hex_i = column - *hex_j - 1;
766 }
767 std::cout << " ConvertColRowToHexManiac column=" << column << " row=" << row
768 << " ... hex_i = " << *hex_i << " hex_j = " << *hex_j << std::endl;
769 if (*hex_i < 0 || *hex_i > 11 || *hex_j < 0 || *hex_j > 11) {
770 fprintf(stderr, "ERROR! BAD hex value!\n");
771 }
772 }
773
774 // Does the inverse of ConvertColRowToHexManiac
775 // Input of 10:1 should be 12:1
776 void ConvertHexManiacToColRow(int hex_i, int hex_j, int* column, int* row) {
777 fprintf(stderr, "ENTERED ConvertHexManiacToColRow %d %d\n", hex_i, hex_j);
778 if (hex_i + hex_j >= 11) { // FIXME -- magic number (11)
779 *column = hex_i + hex_j + 1;
780 *row = hex_j - *column + 11 + 1;
781 } else {
782 // input of hex 1:8 => 10:9
783 *row = hex_j + 1;
784 *column = hex_i + *row;
785 }
786 fprintf(stderr, " ... done conversion");
787 fprintf(stderr, " ... result is %d:%d\n", *column, *row);
788 std::cout << " ConvertHexManiacToColRow " << hex_i << ":" << hex_j
789 << " ... " << *column << ":" << *row << std::endl;
790 }
791
792
793 } // empty namepsace
OLDNEW
« no previous file with comments | « experimental/hex/hex_instance.cc ('k') | experimental/hex/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698