bool CGLRTable::Verify(const yvector< yvector<CSLRCell> >& table) const { yset<const CGLRRuleInfo*> rules1, rules2; for (size_t row = 0; row < Rows; ++row) for (size_t column = 0; column < Columns; ++column) { const CSLRCell& cell = table[row][column]; YASSERT(cell.IsEmpty() == IsEmptyCell(row, column)); if (cell.IsEmpty()) continue; ui32 encoded = GetEncodedCell(row, column); if (IsSimpleCell(encoded)) { YASSERT(cell.m_bShift == false); YASSERT(cell.m_GotoLine == -1); YASSERT(cell.m_ReduceRules.size() == 1); YASSERT(&GetSimpleCellRule(encoded) == cell.m_ReduceRules[0]); } else { ui32 gotoLine; if (GetGotoLine(encoded, gotoLine)) YASSERT(cell.m_GotoLine == (int)gotoLine); else YASSERT(!cell.m_bShift); //YASSERT(cell.m_bShift == ComplexCells[DecodeIndex(encoded)].HasGotoLine()); // compare reduce rules without ordering rules1.clear(); for (TRuleIter ruleIter = IterComplexCellRules(encoded); ruleIter.Ok(); ++ruleIter) rules1.insert(&*ruleIter); rules2.clear(); rules2.insert(cell.m_ReduceRules.begin(), cell.m_ReduceRules.end()); YASSERT(rules1 == rules2); } } return true; }
int FindSudoku_Util(int buffer[V][V]){ int row; int col; if(!IsEmptyCell(buffer,&row,&col)){ return 1; } int i; for(i=1;i<=9;i++){ if(IsSafe(buffer,row,col,i)){ buffer[row][col]=i; if(FindSudoku_Util(buffer)){ return 1; }else{ buffer[row][col]=0; } } } return 0; }
byte* Field::TryBeat(Cell from, Cell to, byte* prevBuffer) { // correctness checking if (!from.IsGood() || !to.IsGood()) return false; if (!from.IsBlack() || !to.IsBlack()) return false; if (!IsMyChecker(from) || !IsEmptyCell(to)) return false; byte* result = NULL; if ((!myCheckers[from]->isQueen()) && (abs(from.row - to.row) == 2) && (abs(from.column - to.column) == 2)) { Cell beaten((max(from.row, to.row) + min(from.row, to.row)) / 2, (max(from.column, to.column) + min(from.column, to.column)) / 2); if (enemyCheckers.Contains(beaten)) result = Beat(from, to, beaten, prevBuffer); } else if ((myCheckers[from]->isQueen()) && (abs(from.row - to.row) == abs(from.column - to.column))) { Cell current, beaten; for (byte i = 1; i < abs(from.row - to.row); i++) { current.row = (from.row < to.row) ? from.row + i : from.row - i; current.column = (from.column < to.column) ? from.column + i : from.column - i; // only one enemy checker in a given row can be beaten if (enemyCheckers.Contains(current)) if (!beaten.IsGood()) beaten = current; else result = NULL; } if (beaten.IsGood()) result = Beat(from, to, beaten, prevBuffer); } return result; }
// tries moving checker from one cell to another (maybe with beats) // returns: NULL if failed, otherwise byte array to be sent to another player byte* Field::TryComplexMove(Cell from, Cell to, byte* prevBuffer) { // correctness checking if (!from.IsGood() || !to.IsGood()) return false; if (!from.IsBlack() || !to.IsBlack()) return false; if (!IsMyChecker(from) || !IsEmptyCell(to)) return false; // once preserve space enought to store info about all possible beats if (!prevBuffer) { if (!(prevBuffer = new byte[packetSize])) return NULL; for (int i = 0; i < packetSize; prevBuffer[i++] = 0); } byte* subResult; // if no beats before checker can simply move if (prevBuffer[0] == 0 && (subResult = TryMove(from, to))) return subResult; // try to beat enemy and land on "to" cell if (subResult = TryBeat(from, to, prevBuffer)) return subResult; // recursively beat enemy checkers List jumps = GetAvailableBeatJumps(from); int before; // for backup for (int i = 0; i < jumps.Count(); i++) { before = strlen(prevBuffer); if (TryBeat(from, *jumps[i], prevBuffer)) { // if we can beat, check for the next beat if (TryComplexMove(*jumps[i], to, prevBuffer)) return prevBuffer; else { // if recursive beats fails, restore backup info Cell beaten((max(from.row, jumps[i]->row) + min(from.row, jumps[i]->row)) / 2, (max(from.column, jumps[i]->column) + min(from.column, jumps[i]->column)) / 2); enemyCheckers.Add(beaten); myCheckers[*jumps[i]]->MoveChecker(from); for (int i = before, len = strlen(prevBuffer); i < len; prevBuffer[i++] = 0); } } } jumps.Clear(); if (!strlen(prevBuffer)) { delete [] prevBuffer; prevBuffer = NULL; } return NULL; }
byte* Field::TryMove(Cell from, Cell to) { if (!myCheckers[from]->isQueen() && (from.row - to.row == 1) && (abs(from.column - to.column) == 1)) { if (to.row == 0) myCheckers[from]->MakeQueen(); myCheckers[from]->MoveChecker(to); return GetTurnInfo(from, to); } else if (myCheckers[from]->isQueen() && (abs(from.row - to.row) == abs(from.column - to.column))) { for (byte i = 1; i < abs(from.row - to.row); i++) { byte row = (from.row < to.row) ? from.row + i : from.row - i; byte column = (from.column < to.column) ? from.column + i : from.column - i; if (!IsEmptyCell(Cell(row, column))) return NULL; } myCheckers[from]->MoveChecker(to); return GetTurnInfo(from, to); } else return NULL; }