Sukodu 求解程序
(2008-04-05 18:58:21)
下一个
这是我2006年写的Sukodu 计算程序,可以求解大部分问题. 有些难题不能完成填空.
int gData[LENGTH]= { //hard, unsolved 2,0,0, 0,8,0, 6,0,7, 0,0,0,0,0,0,0, 0,3,6, 9,0,0, 0,0,0, 0,0,0,0,0,0,0, 0,0,0, 0,0,0, 0,1,0, 0,0,0,0,0,0,0, 0,0,0, 0,3,4, 0,0,5, 0,0,0,0,0,0,0, 0,0,4, 6,0,5, 1,0,0, 0,0,0,0,0,0,0, 7,0,0, 2,9,0, 0,0,0, 0,0,0,0,0,0,0, 0,8,0, 0,0,0 ,0,0,0, 0,0,0,0,0,0,0, 0,7,0, 0,0,6, 8,3,0, 0,0,0,0,0,0,0, 1,0,2, 0,4,0, 0,0,0, 0,0,0,0,0,0,0//192};
#include "assert.h"#include // Header File For Windows#include // Header File For Standard Input / Output#include // Header File For The OpenGL32 Library#include // Header File For The GLu32 Library#include // Header File For The Glaux Library#include #include using namespace std;#define SQURE 3#define WIDTH 9#define LENGTH WIDTH * 16enum{ BLOCKREGION =1, ROWREGION = 2, COLREGION};#include "puzzle.h"//sudoku puzzle solver class by jesse sun 2006class Solve{public: int mBlockData[WIDTH * 3][WIDTH]; int mBoard[LENGTH]; int mBoardMask[LENGTH]; //int mRowSum[WIDTH]; //int mColSum[WIDTH]; int mBlockSum[WIDTH * 3]; int GetIndex(int row, int col) { return (row <<4) + col; } void IndextoRowCol(int index, int& row, int & col) { row = index >> 4; col = index & 0xf; } //initialize data mask and region void Init() { for (int row = 0; row < WIDTH ; row ++) for (int col = 0; col < WIDTH ; col ++) { int hi = row / SQURE; int lo = row % SQURE; int hiindex = col / SQURE; int loindex = col % SQURE; int block = hi * SQURE + hiindex; int index = lo * SQURE + loindex; mBlockData[block][index] = GetIndex(row, col); } int block = WIDTH; for (row = 0; row < WIDTH ; row ++, block++) for (int col = 0; col < WIDTH ; col ++) mBlockData[block][col] = GetIndex(row, col); for (int col = 0; col < WIDTH ; col ++, block++) for (row = 0; row < WIDTH ; row ++) mBlockData[block][row] = GetIndex(row, col); for (int i = 0; i < sizeof(gData) / sizeof(gData[0]); i ++) mBoard[i] = gData[i]; for (i = 0; i < WIDTH * 3; i ++) { //mRowSum[row] = 0; //mColSum[row] = 0; mBlockSum[i] = 0; } } inline void ReSetBit(int& data, int bit, bool &rbChange) { if ((data & (1<>bit) & 0x1; } int FindAviBit(int mask, vector *pArray = NULL)//Count available number { int count = 0; int data = mask; for (int bit = 0; bit < WIDTH; bit ++, data >>= 1) { if ((data & 0x1) == 0) { count ++; if (pArray) pArray->push_back(bit + 1); } } return count; } //Only one number available at a cell. int FindOnlyNumberForCell() { for (int row = 0; row < WIDTH ; row ++) for (int col = 0; col < WIDTH ; col ++) { int index = GetIndex(row, col); if (mBoard[index] == 0) { vector bitarray; int count = FindAviBit(mBoardMask[index], &bitarray); if (count == 1) { mBoard[index ] = bitarray[0]; return index; } } } return -1; } //number not available for the row void MaskDataRow(int row, int data) { int index = GetIndex(row, 0); for (int col = 0; col < WIDTH ; col ++) { SetBit(mBoardMask[index++], data - 1); } } //number not available for the col void MaskDataCol(int col, int data) { int index = col; for (int row = 0; row < WIDTH; row ++) { SetBit(mBoardMask[index], data -1); index += 0x10; } } //number not available for the block void MaskDataBlock(int block, int data) { for (int i = 0; i < WIDTH ; i ++) { int index= mBlockData[block][i]; SetBit(mBoardMask[index], data - 1); } } //initialize the mask void MaskData() { for (int row = 0; row < WIDTH ; row ++) for (int col = 0; col < WIDTH ; col ++) { int index = GetIndex(row, col); int data = mBoard[index]; if (data) MaskData(row, col, data); } } //row col to block number inline int GetBlockNum(int row, int col) { int hi = row / SQURE; int hiindex = col /SQURE; return hi * SQURE + hiindex; } inline int GetBlockNum(int index) { int row, col; IndextoRowCol(index, row, col); return GetBlockNum(row, col); } //a number is known at given(row, col), mask the number out for same row, col, region void MaskData(int row, int col, int data) { if (data) { MaskDataRow(row, data); MaskDataCol(col, data); int block = GetBlockNum(row, col); MaskDataBlock(block, data); SetBit(mBlockSum[row + WIDTH], data - 1); SetBit(mBlockSum[col + WIDTH + WIDTH ], data - 1); SetBit(mBlockSum[block], data - 1); int index = GetIndex(row, col); mBoardMask[index] = ~(1 << data -1); } } //given a number, find it's available postion in a row, col, region int SearchAvlPosition(int *BlockPos, int bit, vector< int>& rArray) { for (int i = 0; i < WIDTH; i++) { int index = BlockPos[i]; if (mBoard[index] == 0) //this cell missing number { if (GetBit(mBoardMask[index], bit) == 0)//does the number available at this cell? { rArray.push_back(index); if (rArray.size() == SQURE + 1) break; } } } return rArray.size(); } //find a missing number with one available position int ThinkOneBlock(int *BlockPos, int mask, int& Data) { for (int bit = 0; bit < WIDTH; bit++, mask >>= 1) { if ((mask & 0x1) ==0)//a number is missing in this block { vector< int> array; SearchAvlPosition(BlockPos, bit, array); if (array.size() == 1) { Data = bit + 1; return array[0]; } } } return -1; } //Find the only number available for a region, row, col int ThinkOneBlock() { int index = -1; for (int block = 0; block < WIDTH * 3; block ++) { int mask = mBlockSum[block]; int bit; index = ThinkOneBlock(mBlockData[block], mask, bit); if (index >= 0) { mBoard[index] = bit; return index; } } return -1; }#define USE //SubGroup, Hidden Twin exclusion rule, naked twin exclusion bool Discovery() { bool change = false; for (int bit = 0; bit < WIDTH ; bit ++) { XWingSwordfish(bit, ROWREGION); XWingSwordfish(bit, COLREGION); } for (int block = 0; block < WIDTH * 3; block ++) { int mask = mBlockSum[block]; int flag = block / WIDTH +1; if (SearchSubGroup(mBlockData[block], mask, flag)) change = true;#ifdef USE if (SearchBlockHiddenTwin(mBlockData[block], mask)) change = true; if (SearchBlockNakedTwin(mBlockData[block], mask)) change = true; //not useful#endif } for (block = 0; block < WIDTH; block ++) { int mask = mBlockSum[block]; int flag = block / WIDTH +1; if (SearchSpecialGroup(mBlockData[block], mask, flag)) change = true; } for (bit = 0; bit < WIDTH ; bit ++) { IsSpecialXwing(bit, ROWREGION); IsSpecialXwing(bit, COLREGION); } return change; } // 78 ---- 18 8 --- 18 <---- invalid // | | | | // 178X --- 17 --> 7 --- 1 // 7 is impossible at lower left corner bool IsSpecialXwing(int Number, int BlockFlag) { bool change = false; //return change; vector< vector > pos_arrays; vector< int > pos_count; int start = WIDTH; if (BlockFlag == ROWREGION) start = WIDTH; else start = WIDTH * 2; for (int block = start; block < start + WIDTH; block++) { vector array; SearchAvlPosition(mBlockData[block], Number, array); pos_arrays.push_back(array); pos_count.push_back(array.size()); } int i; for (i = 0; i < WIDTH ; i++) { if (pos_count[i] != 2) continue; for (int j = 0; j < WIDTH; j++) { if (pos_count[j] > 3 || j == i || pos_count[j] == 0) continue; for (int k = 0; k < pos_arrays[j].size(); k++) { int col, row; int index = pos_arrays[j][k]; int mask = mBoardMask[index]; vector bitarray; int avl = FindAviBit(mask, &bitarray); if (avl != 2) continue; IndextoRowCol(index, row, col); int cornerindex, nakedindex; if (IsSameRowCol(row, col, pos_arrays[i], BlockFlag, cornerindex)) { int mask = mBoardMask[cornerindex]; vector bitarrayc; avl = FindAviBit(mask, &bitarrayc); if (avl != 2) continue; int row0, col0; int rown, coln; IndextoRowCol(cornerindex, row0, col0); if (BlockFlag ==ROWREGION) { rown = row0; coln= col; row0 = row; nakedindex = GetIndex(row, col0); } else { rown = row; coln = col0; col0 = col; nakedindex = GetIndex(row0, col); } int bit1 = (bitarray[0] - 1 == Number) ? bitarray[1] -1: bitarray[0]-1; int bit2 = (bitarrayc[0] -1 == Number) ? bitarrayc[1] -1: bitarrayc[0]-1; if (bit1==bit2) continue; if (IsTwinNumber(row0, col0, bit1, bit2, rown, coln)) { //if they are naked TWIN int index1; if (BlockFlag ==ROWREGION) index1 = GetIndex(i, col); else index1 = GetIndex(row, i); Print(); ReSetBit(mBoardMask[index1], Number, change); char buf[200]; sprintf(buf, "postion %x can not be %d because of n=%x c=%xspecial %d %d", index1, Number+1, nakedindex, cornerindex, bit1+1, bit2+1); PrintLog(buf); } } } } } return change; } bool IsTwinNumber(int row, int col, int bit1, int bit2, int rown, int coln) { int index= GetIndex(row, col); int mask = ~((1 << bit1) | (1 < bitarrayc; int avl = FindAviBit(mBoardMask[index], &bitarrayc); if (avl != 2) return false; int bit3, bit4; bool ok = false; for (int i = 0; i < 2; i ++) { if (bitarrayc[i] -1 == bit1) { bit3 = bitarrayc[1 - i] - 1; bit4 = bit2; ok = true; } else if (bitarrayc[i] -1 == bit2) { bit3 = bitarrayc[1 - i] - 1; bit4 = bit1; ok = true; } } if (ok == false) return false; for (i = 0 ; i < WIDTH; i ++) { int indexnew = GetIndex(i, col); int mask = ~((1 << bit3) | (1 <& pos1, int BlockFlag, int &rOtherIndex) { for (int i = 0; i < pos1.size(); i++) { int col, row; IndextoRowCol(pos1[i], row, col); if (BlockFlag ==ROWREGION) { if (col == ColTest) break; } else { if (row == RowTest) break; } } if (i == 0) rOtherIndex = pos1[1]; else rOtherIndex = pos1[0]; return i < pos1.size(); } // 36 | 6 36 369X | <---- 3 is impossible here // 39 69 | 9 69 <-- invalid 39 3x | // ------------ ---------- // 6X X 69 // 369X -----> 3 // the lower left 3 is impossible, cause it will lead a unsolvable 69 position bool SearchSpecialGroup(int *BlockPos, int mask, int BlockFlag) { bool change = false; for (int bit = 0; bit < WIDTH; bit++, mask>>=1) { if ((mask & 0x1) != 0)//a number is missing in this block continue; vector array; int size = SearchAvlPosition(BlockPos, bit, array); if (size < 2) continue; //A number apears 3 (or more ) times in this block for (int i = 0; i < size-1; i++) //major test cell { int col0, row0; IndextoRowCol(array[i], row0, col0); for (int j = i+1; j < size; j++) { bool samerow = 0; bool samecol= 0; int row, col; IndextoRowCol(array[j], row, col); //a number is at same row or col in this block int block=0; if (row == row0) { block = WIDTH + row0; samerow = true; } else if (col == col0) { block = WIDTH * 2 + col0; samecol = true; } else continue; vector arrayother; int size2 = SearchAvlPosition(mBlockData[block], bit, arrayother); if (size2 < 3) continue; int row2, col2, index2; int block0 = GetBlockNum(array[i]); for (int k = 0; k < arrayother.size(); k++)//for 3rd number { IndextoRowCol(arrayother[k], row2, col2); int block3 = GetBlockNum(arrayother[k]); if (block3 != block0) break; } if (k == arrayother.size()) { for (k = 0; k < size; k++) if (k != i && k != j) break; if (k == size) continue; IndextoRowCol(array[k], row2, col2); } index2 = GetIndex(row2, col2); //third number exists at same row /col/block for this numbers, //so it will exclude the other 2 positions in the block vector bitarray1; int mask = mBoardMask[array[i]]; int avl = FindAviBit(mask, &bitarray1); vector bitarray2; mask = mBoardMask[array[j]]; avl = FindAviBit(mask, &bitarray2); for (k = 0; k < bitarray1.size(); k++)//for other number in first cell { int bitk = bitarray1[k]-1; if (bitk == bit) continue; for (int m = 0; m < bitarray2.size(); m++)//for other number in second cell { int bitm = bitarray2[m]-1; if (bitm == bit || bitm == bitk) continue; //find two other different number mask = ~(GetMaskFromBit(bitk) | GetMaskFromBit(bitm)); for (int ind = 0; ind < WIDTH; ind++) { int index = mBlockData[block0][ind]; if (index == array[i] || index == array[j] || index == index2) continue; if (TestMask(index, mask))//they are TWIN number { break; } } if (ind == WIDTH) for (ind = 0; ind < WIDTH; ind++) { int index = mBlockData[block][ind]; if (index == array[i] || index == array[j] || index == index2) continue; if (TestMask(index, mask)) { break; } } if (ind < WIDTH) { //if bitk & bitm are TWIN mask = ~(GetMaskFromBit(bit) | GetMaskFromBit(bitk)); bool ok1; ok1 = IsRelatedNumber(mask, array[i], block, bitk, array[i], array[j], index2); bool ok2; ok2 = ok1 && IsRelatedNumber(mask, array[j], block, bitm, array[i], array[j], index2); if (ok1 && ok2) //exlcude bit from (row2, col2) { //Print(); int index = GetIndex(row2, col2); ReSetBit(mBoardMask[index], bit, change); } } } } } } } return change; } bool TestMask(int index, int mask) { mask &= 0x1ff; return mBoard[index] ==0 && (mBoardMask[index] & mask) == mask; } bool IsRelatedNumber(int mask, int index, int block, int bit, int row0, int row1, int row2) { //Is bitk the only number in this row/col except known three position pos[i], pos[j], (row2,col2) // or Is the bitk the only number other than bit bool ok1 = true; if (!TestMask(index, mask)) { ok1 = true; vector array; SearchAvlPosition(mBlockData[block], bit, array); for (int n = 0; n < array.size(); n++) { if (array[n] != row0 && array[n] != row1 && array[n] != row2) { ok1 = false; break; } } } return ok1; } bool IsXWing(int size, vector& pos1, vector& pos2, vector& pos3, vector& Rows, vector& Cols) { set rows; set cols; for (int i = 0; i < pos1.size(); i++) { int col, row; IndextoRowCol(pos1[i], row, col); cols.insert(col); rows.insert(row); } for (i = 0; i < pos2.size(); i++) { int col, row; IndextoRowCol(pos2[i], row, col); cols.insert(col); rows.insert(row); } for (i = 0; i < pos3.size(); i++) { int col, row; IndextoRowCol(pos3[i], row, col); cols.insert(col); rows.insert(row); } if (rows.size() == cols.size() && cols.size() == size) { set::iterator it; for (it = rows.begin(); it != rows.end(); it++) { Rows.push_back(*it); } for (it = cols.begin(); it != cols.end(); it++) { Cols.push_back(*it); } return true; } else return false; } bool ExcluseXwing(vector& rows, vector& cols, int Number, int BlockFlag, bool& change) { { //find a XWing, vector rowsmask; rowsmask.resize(WIDTH, false); for (int i = 0; i < rows.size(); i++) { rowsmask[ rows[i] ] = true; } for (i = 0; i < cols.size(); i++) { int col = cols[i]; for (int row = 0; row < WIDTH; row++) { if (rowsmask[row] == false) { //exclude number for the cell int index = GetIndex(row, col); if (BlockFlag == COLREGION) index = GetIndex(col, row); ReSetBit(mBoardMask[index], Number, change); } } } } return true; } bool XWingSwordfish(int Number, int BlockFlag) { bool change = false; //return change; vector< vector > pos_arrays; vector< int > pos_count; int start = WIDTH; if (BlockFlag == ROWREGION) start = WIDTH; else start = WIDTH * 2; for (int block = start; block < start + WIDTH; block++) { vector array; SearchAvlPosition(mBlockData[block], Number, array); pos_arrays.push_back(array); pos_count.push_back(array.size()); } int i; for (i = 0; i < WIDTH -1; i++) { if (pos_count[i] != 2) continue; for (int j = i + 1; j < WIDTH; j++) { if (pos_count[j] != 2) continue; vector tmp; vector rows, cols; if (IsXWing(2, pos_arrays[i], pos_arrays[j], tmp, rows, cols)) { //Exclulde rowcol if (BlockFlag != ROWREGION) ExcluseXwing(cols, rows, Number, BlockFlag, change); else ExcluseXwing(rows, cols, Number, BlockFlag, change); } } } for (i = 0; i < WIDTH - 2; i++) { if (pos_count[i] > 3 || pos_count[i] == 0) continue; for (int j = i + 1; j < WIDTH-1; j++) { if (pos_count[j] > 3 || pos_count[j] == 0) continue; for (int k = j + 1; k < WIDTH; k++) { if (pos_count[k] > 3) continue; vector rows, cols; if (IsXWing(3, pos_arrays[i], pos_arrays[j], pos_arrays[k], rows, cols)) { if (BlockFlag != ROWREGION) ExcluseXwing(cols, rows, Number, BlockFlag, change); else ExcluseXwing(rows, cols, Number, BlockFlag, change); } } } } if (change) { char buf[200] = ""; sprintf(buf, "Xwing Found Number = %d", Number+1); PrintLog(buf); } return change; } //sub group exclusion bool SearchSubGroup(int *BlockPos, int mask, int BlockFlag) { bool change = false; for (int bit = 0; bit < WIDTH; bit++, mask >>= 1) { if ((mask & 0x1) == 0)//a number is missing in this block { vector< int> array; int size = SearchAvlPosition(BlockPos, bit, array); if (size >= 2 && size <= SQURE) { int col0, row0; IndextoRowCol(array[0], row0, col0); bool samerow = false; bool samecol= false; bool sameblock = false; int block; if (BlockFlag == BLOCKREGION)//within a block, { //if the number is available at same row or col samerow = true; samecol= true; for (int i = 1; i < array.size(); i++) { int row, col; IndextoRowCol(array[i], row, col); if (row != row0) samerow = false; if (col != col0) samecol = false; } if (samerow) block = WIDTH + row0; else if (samecol) block = WIDTH * 2 + col0; } else if (BlockFlag != BLOCKREGION) //at a row or col { //if the number is within a block sameblock = true; block = GetBlockNum(array[0]); for (int i = 1; i < array.size(); i++) { if (block != GetBlockNum(array[i])) sameblock = false; } } //exclude the number from other row/col of same block if (sameblock || samerow || samecol) { int col0, row0; IndextoRowCol(array[0], row0, col0); int block0 = GetBlockNum(row0, col0); for (int i = 0; i < WIDTH; i ++) { int index = mBlockData[block][i]; int row, col; IndextoRowCol(index, row, col); if ((BlockFlag == ROWREGION && row != row0) || (BlockFlag == COLREGION && col != col0) || BlockFlag == BLOCKREGION && GetBlockNum(index) != block0) { //SetBit(mBoardMask[index], bit); ReSetBit(mBoardMask[index], bit, change); } } char buf[200] = ""; sprintf(buf, "RowCol Gird %x, %x is subgroup %d", array[0], array[1], bit+1); PrintLog(buf); } } } } return change; } //naked twins/triple bool SearchBlockNakedTwin(int *BlockPos, int BlockMask) { bool change = false; for (int i = 0; i < WIDTH - 1; i++) { if (GetBit(BlockMask, i) != 0) //does i missing in this block continue; int mask = mBoardMask[BlockPos[i]]; vector bitarray; int avl = FindAviBit(mask, &bitarray); if (avl != 2 && avl != 3 ) continue; vector array; for (int j = i + 1; j < WIDTH; j++) if (mask == mBoardMask[BlockPos[j]]) {//Found Naked Twin/triple Cell array.push_back(j); } //2 or 3 cell has same mask, same available number(s) if (array.size() == avl - 1) { int pos1 = array[0]; int pos2 = pos1; if (avl == 3) pos2 = array[1]; for (int j = 0; j < WIDTH; j++) { if (j != i && j != pos1 && j != pos2) { //exlcude twins from remaining position int bitmask = (~mask) & 0x1ff; if ((mBoardMask[BlockPos[j]] & bitmask) != bitmask) {//if the cell contains any of number in bitarray mBoardMask[BlockPos[j]] |= bitmask; change = true; char buf[200]; sprintf(buf, "Gird %x, %x is Naked twins for mask %d %d ", BlockPos[i], BlockPos[pos1], bitarray[0], bitarray[1]); PrintLog(buf); } } } } } return change; } //search hidden twins or tripple bool SearchBlockHiddenTwin(int *BlockPos, int mask) { bool change = false; for (int i = 0; i < WIDTH - 1; i++) { if (GetBit(mask, i) != 0) //does i missing in this block continue; vector< int> array; int avl = SearchAvlPosition(BlockPos, i, array); if (avl != 2 && avl != 3) continue; vector< int> numbers; for (int j = i + 1; j < WIDTH; j++) { if (GetBit(mask, j) != 0) //does j missing in this block continue; vector< int> array2; int avl2 = SearchAvlPosition(BlockPos, j, array2); if (avl2 != avl) continue; //does number i & j have same position in the block if ((array[0]== array2[0] && array[1]== array2[1]) && (avl == 2 || (array[2]== array2[2]))) {//find hidden twins numbers.push_back(j); } } if ( avl == numbers.size() + 1) { int j = numbers[0]; int tnwmask = ~((1<<<< k); pos2 = array[2]; } //tnwmask &= 0x1ff; //if (!TestMask(array[0], tnwmask) || !TestMask(array[1], tnwmask) || !TestMask(pos2, tnwmask)) if (mBoardMask[array[0]] != tnwmask || mBoardMask[array[1]] != tnwmask || mBoardMask[pos2] != tnwmask) { change = true; char buf[200]; sprintf(buf, "Gird %x, %x is hidden twins for %d, %d", array[0], array[1], i+1, j+1); PrintLog(buf); } mBoardMask[array[0]] = tnwmask; mBoardMask[array[1]] = tnwmask; } } return change; } int GetMaskFromBit(int bit) { return (1 << bit) & 0x1ff; } void ThinkAll() { int index = -1; bool bfirst = true; do {retry: index = ThinkOneBlock(); if (index == -1) index = FindOnlyNumberForCell(); if (index == -1) { if (bfirst) { while( Discovery() ) ; Discovery(); bfirst = false; goto retry; } } if (index >= 0) { bfirst = true; int data = mBoard[index]; if (data) { int row, col; IndextoRowCol(index, row, col); MaskData(row, col, data); char buf[200]; sprintf(buf, "Gird %0x is number %d", index, data); PrintLog(buf); } } } while(index >= 0); return; } Solve() { Init(); PrintLog(NULL); MaskData(); ThinkAll(); Print(); } void PrintLog(char *info) { char *att = "at"; if (info == NULL) att = "wt"; FILE * fp = fopen("c:\\output.txt", att); if (fp == NULL) return; if (info) fprintf(fp, "%s\n", info); fclose(fp); } void Print() { FILE * fp = fopen("c:\\output.txt", "at"); for (int row = 0; row < WIDTH ; row ++) { for (int col = 0; col < WIDTH ; col ++) { int index = GetIndex(row, col); printf("%d ", mBoard[index]); fprintf(fp, "%d ", mBoard[index]); } printf("\r\n"); fprintf(fp, "\n"); } fprintf(fp, "\n"); for ( row = 0; row < WIDTH ; row ++) { for (int col = 0; col < WIDTH ; col ++) { int index = GetIndex(row, col); char buf[200] = ""; if (mBoard[index] == 0) { int mask = mBoardMask[index]; vector array; int count = FindAviBit(mask, &array); for (int i = 0; i < array.size(); i ++) { sprintf(buf + strlen(buf), "%d", array[i]); } } else { sprintf(buf, "%d",mBoard[index]); } printf("%d ", mBoard[index]); fprintf(fp, "%5s ", buf); } printf("\r\n"); fprintf(fp, "\n"); } fprintf(fp, "\n"); fclose(fp); for (int col = 0; col < WIDTH ; col ++) { int sum = 0; for (int row = 0; row < WIDTH ; row ++) { int index = GetIndex(row, col); sum += mBoard[index]; } //assert(sum==45); } } void DrawBoard() { extern GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...); int count = 0 ; for (int row = 0; row < WIDTH ; row ++) { for (int col = 0; col < WIDTH ; col ++) { int index = GetIndex(row, col); int set = 0; glColor3f(1, 0, 0); // Set Color To Purple if (gData[index ] != mBoard[index]) { //set = 1; glColor3f(1.0f,1.0f,0.0f); glColor3f(0,1.0f,0.0f); count ++; } char buf[100] = "0"; int delta = 0; if (SQURE == 4) delta = -1; if (mBoard[index]) sprintf(buf, "%X", mBoard[index] + delta); glPrint(380 + col * 24, 70 + row * 30, set, buf); //glPrint(380 + col * 24, 70 + row * 25, set, buf); //glPrint(200 + col * 32, 70 + row * 25, set, "%d", mBoard[index]); } } glPrint(430 , 40, 0, "%d", count); }};Solve gSolve;void drawpuzzle(){ gSolve.DrawBoard();}