/******************************************************** *! @brief 垂直位置取得関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PRIVATE void GetVerticalPos( REAL_POS *pInputV ) { int v; printf("[縦方向(1~8)]\n>>"); scanf("%d" ,&v ); *pInputV = REALV(v); }
int const_lt(Const cleft, Const cright) /*;const_lt*/ { switch (const_cmp_kind(cleft, cright)) { case CONST_INT : return (INTV(cleft)<INTV(cright)); case CONST_UINT : return int_lss(UINTV(cleft), UINTV(cright)); case CONST_FIXED : return (FIXEDV(cleft)<FIXEDV(cright)); case CONST_RAT : return rat_lss(RATV(cleft), RATV(cright)); case CONST_REAL : return REALV(cleft) < REALV(cright); default : const_cmp_undef(cleft, cright); return 0; } }
/******************************************************** *! @brief 関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PRIVATE int CalcScore( PLAYER_T Player, char aReversiTable[][VERTICAL_NUM][MAX_NUM] ) { int h, v; int Score = 0; for ( v=REALV(1); v < VERTICAL_NUM; v=v+REALV(1) ) { for ( h=REALH(1); h < HORIZON_NUM; h=h+REALH(1) ) { if ( Player == PLAYER_WHITE ) { if ( CheckCellState( h, v, WHITE, aReversiTable ) ) { /* 自分の石だったら加点 */ Score += m_EvaluateWeightTable[h-1][v/COEF_LINE-1]; } else if ( CheckCellState( h, v, BLACK, aReversiTable ) ) { /* 相手の石だったら減点 */ Score -= m_EvaluateWeightTable[h-1][v/COEF_LINE-1]; } else if ( CheckCellState( h, v, EMPTY, aReversiTable ) ) { ; } else { printf("\n Error"); } } else if ( Player == PLAYER_BLACK ) { if ( CheckCellState( h, v, BLACK, aReversiTable ) ) { /* 自分の石だったら加点 */ Score += m_EvaluateWeightTable[h-1][v/COEF_LINE-1]; } else if ( CheckCellState( h, v, WHITE, aReversiTable ) ) { /* 相手の石だったら減点 */ Score -= m_EvaluateWeightTable[h-1][v/COEF_LINE-1]; } else if ( CheckCellState( h, v, EMPTY, aReversiTable ) ) { ; } else { printf("\n Error"); } } } } return Score; }
/******************************************************** *! @brief 関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PUBLIC BOOL IsExistOKNextMove( PLAYER_T Player ) { int h, v; DISC_INFO_T DiscInfo; ERROR_CHECK Result; for ( v=REALV(1); v < VERTICAL_NUM; v=v+REALV(1) ) { for ( h=REALH(1); h < HORIZON_NUM; h=h+REALH(1) ) { DiscInfo.h = h; DiscInfo.v = v; DiscInfo.CurrentPlayer = Player; Result = CheckInputPosOnCurrent( &DiscInfo, FALSE ); if ( Result == SUCCESS ) { return TRUE; } } } return FALSE; }
/******************************************************** *! @brief 関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PUBLIC void GetDiscNum( unsigned int *pNumWhite, unsigned int *pNumBlack, char aReversiTable[][VERTICAL_NUM][MAX_NUM] ) { int h, v; unsigned int NumWhite = 0, NumBlack = 0; for ( v=REALV(1); v < VERTICAL_NUM; v=v+REALV(1) ) { for ( h=REALH(1); h < HORIZON_NUM; h=h+REALH(1) ) { if ( !strcmp( aReversiTable[h][v], m_aCellState[WHITE] ) ) { NumWhite++; } else if ( !strcmp( aReversiTable[h][v], m_aCellState[BLACK] ) ) { NumBlack++; } } } *pNumWhite = NumWhite; *pNumBlack = NumBlack; }
/******************************************************** *! @brief オセロ盤フルチェック関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PUBLIC BOOL IsReversiTableFull( char aReversiTable[][VERTICAL_NUM][MAX_NUM] ) { int h, v; for ( v=1; v < END_OF_POS; v++ ) { for ( h=1; h < END_OF_POS; h++ ) { if ( IsEmptyPos( REALH(h), REALV(v), aReversiTable ) ) { return FALSE; } } } return TRUE; }
void segment_put_const(Segment seg, Const con) /*;segment_put_const*/ { if (con->const_kind == CONST_INT) { /* can safely put integers - defer others for later */ segment_put_word(seg, INTV(con)); } else if(con->const_kind == CONST_REAL) { segment_put_real(seg, REALV(con)); } else if(con->const_kind == CONST_FIXED) { segment_put_long(seg, FIXEDV(con)); } else { #ifdef DEBUG zpcon(con); #endif chaos("segment.c - meaningless kind of literal"); } }
/******************************************************** *! @brief 関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PRIVATE void MakeTree( EVALUATE_TREE_T *pCurrentNode ) { int h, v; DISC_INFO_T DiscInfo; ERROR_CHECK Result; EVALUATE_TREE_T *pNextDepthNode; EVALUATE_TREE_T *pNextNode; if ( pCurrentNode->Depth <= DEPTH_MAX ) { #ifdef DEBUG_MAKE_NODE printf("\nDepth = %d, NodeID = %d, CurrentPlayer = %d, Pos = [%d, %d], Score = %d" ,pCurrentNode->Depth ,pCurrentNode->NodeID ,pCurrentNode->DiscInfo.CurrentPlayer ,pCurrentNode->DiscInfo.h ,pCurrentNode->DiscInfo.v/COEF_LINE ,pCurrentNode->Score ); PrintReversiTable( pCurrentNode->pEvaluatReversiTable->aEvaluatReversiTable ); #endif /* 有効な位置を探す */ for ( v=REALV(1); v < VERTICAL_NUM; v=v+REALV(1) ) { for ( h=REALH(1); h < HORIZON_NUM; h=h+REALH(1) ) { DiscInfo.h = h; DiscInfo.v = v; DiscInfo.CurrentPlayer = TOGGLE_PLAYER( pCurrentNode->DiscInfo.CurrentPlayer ); Result = CheckInputPos( &DiscInfo, pCurrentNode->pEvaluatReversiTable->aEvaluatReversiTable, FALSE ); /* 有効な位置を見つけたら新しいノードを生成する */ if ( Result == SUCCESS ) { if ( pCurrentNode->NumNextIndex == 0 ) { /* 1つでも有効な位置が見つかったら次の深さのノードを生成する */ /* Tableへのポインタは生成し終わったら消滅して欲しいのでスコープは必要最低限に限定する */ EVALUATE_TABLE_T *pNextDepthTable; /* Create Evaluate Table of Next Depth Node */ pNextDepthTable = (EVALUATE_TABLE_T*)malloc( sizeof(EVALUATE_TABLE_T) ); memcpy( pNextDepthTable, pCurrentNode->pEvaluatReversiTable, sizeof(EVALUATE_TABLE_T) ); /* CurrentノードのTableをコピーする */ ReversingDisc( DiscInfo, pNextDepthTable->aEvaluatReversiTable ); /* コピーしたTableで石をひっくり返す */ /* Create Evaluate Tree Next Depth Node */ pCurrentNode->pNextDepthNode = (EVALUATE_TREE_T*)malloc( sizeof(EVALUATE_TREE_T) ); pNextDepthNode = pCurrentNode->pNextDepthNode; /* 確保した領域にポインタを繋ぐ */ pNextDepthNode->Depth = pCurrentNode->Depth + 1; pNextDepthNode->NodeID = pCurrentNode->NumNextIndex; pNextDepthNode->DiscInfo.h = DiscInfo.h; pNextDepthNode->DiscInfo.v = DiscInfo.v; pNextDepthNode->DiscInfo.CurrentPlayer = DiscInfo.CurrentPlayer; pNextDepthNode->pEvaluatReversiTable = pNextDepthTable; pNextDepthNode->Score = CalcScore( pNextDepthNode->DiscInfo.CurrentPlayer, pNextDepthNode->pEvaluatReversiTable->aEvaluatReversiTable ); pNextDepthNode->pNextNode = NULL; pNextDepthNode->pNextDepthNode = NULL; /* Create Evaluate Tree Next Next Depth Node */ MakeTree( pNextDepthNode ); /* 探索深度限界判定 */ if ( pNextDepthNode != NULL ) { /* NextDepthがまだ探索深度限界に達していない */ pNextNode = pNextDepthNode->pNextNode; /* 以後、新しい選択肢が見つかったらNextNodeに新規Nodeを追加していく */ } else { /* NextDepthが探索深度限界に達していた */ return; /* 深度限界なので他の選択肢を探る必要なし */ } } else { /* 次の選択肢が見つかったらノードを生成する */ /* Tableへのポインタは生成し終わったら消滅して欲しいのでスコープは必要最低限に限定する */ EVALUATE_TABLE_T *pNextTable; /* Create Evaluate Table of Next Node */ pNextTable = (EVALUATE_TABLE_T*)malloc( sizeof(EVALUATE_TABLE_T) ); memcpy( pNextTable, pCurrentNode->pEvaluatReversiTable, sizeof(EVALUATE_TABLE_T) ); /* CurrentノードのTableをコピーする */ ReversingDisc( DiscInfo, pNextTable->aEvaluatReversiTable ); /* コピーしたTableで石をひっくり返す */ /* Create Evaluate Tree Next Node */ pNextNode = (EVALUATE_TREE_T*)malloc( sizeof(EVALUATE_TREE_T) ); pNextNode->Depth = pCurrentNode->pNextDepthNode->Depth; pNextNode->NodeID = pCurrentNode->NumNextIndex; pNextNode->DiscInfo.h = DiscInfo.h; pNextNode->DiscInfo.v = DiscInfo.v; pNextNode->DiscInfo.CurrentPlayer = DiscInfo.CurrentPlayer; pNextNode->pEvaluatReversiTable = pNextTable; pNextNode->Score = CalcScore( pNextNode->DiscInfo.CurrentPlayer, pNextNode->pEvaluatReversiTable->aEvaluatReversiTable ); pNextNode->pNextNode = NULL; pNextNode->pNextDepthNode = NULL; /* Create Evaluate Tree Next Depth Next Node */ MakeTree( pNextNode ); /* pNextNodeに今回生成したNodeのNextNodeアドレスを入れておく * 新しい選択肢が見つかったらpNextNodeに追加していく */ pNextNode = pNextNode->pNextNode; } pCurrentNode->NumNextIndex++; /* 有効な選択肢が見つかったら次の深さのノード数をインクリメントする */ } } } } else { /* 評価木の深度が限界に達したので、確保した領域を解放してTree生成終了 */ FREE( pCurrentNode->pEvaluatReversiTable ); FREE( pCurrentNode ); return; } #ifdef DEBUG_MAKE_NODE printf("\n [Depth = %d] NumNextIndex = %d" ,pCurrentNode->Depth ,pCurrentNode->NumNextIndex ); #endif return; }
/******************************************************** *! @brief 石ひっくり返し関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PUBLIC void ReversingDisc( DISC_INFO_T DiscInfo, char aReversiTable[][VERTICAL_NUM][MAX_NUM] ) { PLAYER_T CurrentPlayer; REAL_POS RealH, RealV; int h, v; RealH = DiscInfo.h; RealV = DiscInfo.v; CurrentPlayer = DiscInfo.CurrentPlayer; /* 入力されたセルに石を置く */ DoReverse( CurrentPlayer, RealH, RealV, aReversiTable ); /* 北方向 */ if ( DiscInfo.North == SUCCESS ) { for ( h=0, v=-1; ; v-- ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 北東方向 */ if ( DiscInfo.NorthEast == SUCCESS ) { for ( h=1, v=-1; ; h++, v-- ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 東方向 */ if ( DiscInfo.East == SUCCESS ) { for ( h=1, v=0; ; h++ ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 南東方向 */ if ( DiscInfo.SouthEast == SUCCESS ) { for ( h=1, v=1; ; h++, v++ ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 南方向 */ if ( DiscInfo.South == SUCCESS ) { for ( h=0, v=1; ; v++ ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 南西方向 */ if ( DiscInfo.SouthWest == SUCCESS ) { for ( h=-1, v=1; ; h--, v++ ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 西方向 */ if ( DiscInfo.West == SUCCESS ) { for ( h=-1, v=0; ; h-- ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 北西方向 */ if ( DiscInfo.NorthWest == SUCCESS ) { for ( h=-1, v=-1; ; h--, v-- ) { if ( DoReverse( CurrentPlayer, RealH+REALH(h), RealV+REALV(v), aReversiTable ) ) { break; } } } /* 北東角 */ if ( DiscInfo.EdgeOfNorthEast == SUCCESS ) { if ( CurrentPlayer == PLAYER_WHITE ) { strcpy( aReversiTable[REALH(EIGHT)][REALV(ONE)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(EIGHT)][REALV(TWO)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(SEVEN)][REALV(ONE)], m_aCellState[WHITE] ); } else if ( CurrentPlayer == PLAYER_BLACK ) { strcpy( aReversiTable[REALH(EIGHT)][REALV(ONE)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(EIGHT)][REALV(TWO)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(SEVEN)][REALV(ONE)], m_aCellState[BLACK] ); } } /* 南東角 */ if ( DiscInfo.EdgeOfSouthEast == SUCCESS ) { if ( CurrentPlayer == PLAYER_WHITE ) { strcpy( aReversiTable[REALH(EIGHT)][REALV(EIGHT)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(EIGHT)][REALV(SEVEN)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(SEVEN)][REALV(EIGHT)], m_aCellState[WHITE] ); } else if ( CurrentPlayer == PLAYER_BLACK ) { strcpy( aReversiTable[REALH(EIGHT)][REALV(EIGHT)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(EIGHT)][REALV(SEVEN)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(SEVEN)][REALV(EIGHT)], m_aCellState[BLACK] ); } } /* 南西角 */ if ( DiscInfo.EdgeOfSouthWest == SUCCESS ) { if ( CurrentPlayer == PLAYER_WHITE ) { strcpy( aReversiTable[REALH(ONE)][REALV(EIGHT)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(ONE)][REALV(SEVEN)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(TWO)][REALV(EIGHT)], m_aCellState[WHITE] ); } else if ( CurrentPlayer == PLAYER_BLACK ) { strcpy( aReversiTable[REALH(ONE)][REALV(EIGHT)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(ONE)][REALV(SEVEN)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(TWO)][REALV(EIGHT)], m_aCellState[BLACK] ); } } /* 北西角 */ if ( DiscInfo.EdgeOfNorthWest == SUCCESS ) { if ( CurrentPlayer == PLAYER_WHITE ) { strcpy( aReversiTable[REALH(ONE)][REALV(ONE)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(ONE)][REALV(TWO)], m_aCellState[WHITE] ); strcpy( aReversiTable[REALH(TWO)][REALV(ONE)], m_aCellState[WHITE] ); } else if ( CurrentPlayer == PLAYER_BLACK ) { strcpy( aReversiTable[REALH(ONE)][REALV(ONE)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(ONE)][REALV(TWO)], m_aCellState[BLACK] ); strcpy( aReversiTable[REALH(TWO)][REALV(ONE)], m_aCellState[BLACK] ); } } }
/******************************************************** *! @brief 全方位走査関数 - @param[out] - @param[in] - @par - @return - @note *********************************************************/ PRIVATE void ScanDirection( DISC_INFO_T *pDiscInfo, char aReversiTable[][VERTICAL_NUM][MAX_NUM] ) { PLAYER_T CurrentPlayer; REAL_POS RealH, RealV; int h, v; RealH = pDiscInfo->h; RealV = pDiscInfo->v; CurrentPlayer = pDiscInfo->CurrentPlayer; /* 北方向 */ for ( h=0, v=-1; ; v-- ) { if ( (h == 0) && (v == -1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->North), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->North), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 北東方向 */ for ( h=1, v=-1; ; h++, v-- ) { if ( (h == 1) && (v == -1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->NorthEast), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->NorthEast), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 東方向 */ for ( h=1, v=0; ; h++ ) { if ( (h == 1) && (v == 0) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->East), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->East), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 南東方向 */ for ( h=1, v=1; ; h++, v++ ) { if ( (h == 1) && (v == 1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->SouthEast), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->SouthEast), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 南方向 */ for ( h=0, v=1; ; v++ ) { if ( (h == 0) && (v == 1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->South), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->South), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 南西方向 */ for ( h=-1, v=1; ; h--, v++ ) { if ( (h == -1) && (v == 1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->SouthWest), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->SouthWest), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 西方向 */ for ( h=-1, v=0; ; h-- ) { if ( (h == -1) && (v == 0) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->West), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->West), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 北西方向 */ for ( h=-1, v=-1; ; h--, v-- ) { if ( (h == -1) && (v == -1) ) { /* 隣接マス */ if ( IsScanFinish( &(pDiscInfo->NorthWest), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), TRUE, aReversiTable ) ) { break; } } else { /* 隣接マス以降 */ if ( IsScanFinish( &(pDiscInfo->NorthWest), CurrentPlayer, RealH+REALH(h), RealV+REALV(v), FALSE, aReversiTable ) ) { break; } } } /* 北東角 */ pDiscInfo->EdgeOfNorthEast = ERROR; if ( ((RealH == EIGHT) && (RealV == REALV(TWO))) || ((RealH == SEVEN) && (RealV == REALV(ONE))) ) { /* 白のターン */ if ( CurrentPlayer == PLAYER_WHITE ) { if ( CheckCellState( REALH(EIGHT), REALV(ONE), BLACK, aReversiTable ) ) { if ( ( CheckCellState( REALH(EIGHT), REALV(TWO), WHITE, aReversiTable ) ) || ( CheckCellState( REALH(SEVEN), REALV(ONE), WHITE, aReversiTable ) ) ) { pDiscInfo->EdgeOfNorthEast = SUCCESS; } } /* 黒のターン */ } else if ( CurrentPlayer == PLAYER_BLACK ) { if ( CheckCellState( REALH(EIGHT), REALV(ONE), WHITE, aReversiTable ) ) { if ( ( CheckCellState( REALH(EIGHT), REALV(TWO), BLACK, aReversiTable ) ) || ( CheckCellState( REALH(SEVEN), REALV(ONE), BLACK, aReversiTable ) ) ) { pDiscInfo->EdgeOfNorthEast = SUCCESS; } } } } /* 南東角 */ pDiscInfo->EdgeOfSouthEast = ERROR; if ( ((RealH == EIGHT) && (RealV == REALV(SEVEN))) || ((RealH == SEVEN) && (RealV == REALV(EIGHT))) ) { /* 白のターン */ if ( CurrentPlayer == PLAYER_WHITE ) { if ( CheckCellState( REALH(EIGHT), REALV(EIGHT), BLACK, aReversiTable ) ) { if ( ( CheckCellState( REALH(EIGHT), REALV(SEVEN), WHITE, aReversiTable ) ) || ( CheckCellState( REALH(SEVEN), REALV(EIGHT), WHITE, aReversiTable ) ) ) { pDiscInfo->EdgeOfSouthEast = SUCCESS; } } /* 黒のターン */ } else if ( CurrentPlayer == PLAYER_BLACK ) { if ( CheckCellState( REALH(EIGHT), REALV(EIGHT), WHITE, aReversiTable ) ) { if ( ( CheckCellState( REALH(EIGHT), REALV(SEVEN), BLACK, aReversiTable ) ) || ( CheckCellState( REALH(SEVEN), REALV(EIGHT), BLACK, aReversiTable ) ) ) { pDiscInfo->EdgeOfSouthEast = SUCCESS; } } } } /* 南西角 */ pDiscInfo->EdgeOfSouthWest = ERROR; if ( ((RealH == ONE) && (RealV == REALV(SEVEN))) || ((RealH == TWO) && (RealV == REALV(EIGHT))) ) { /* 白のターン */ if ( CurrentPlayer == PLAYER_WHITE ) { if ( CheckCellState( REALH(ONE), REALV(EIGHT), BLACK, aReversiTable ) ) { if ( ( CheckCellState( REALH(ONE), REALV(SEVEN), WHITE, aReversiTable ) ) || ( CheckCellState( REALH(TWO), REALV(EIGHT), WHITE, aReversiTable ) ) ) { pDiscInfo->EdgeOfSouthWest = SUCCESS; } } /* 黒のターン */ } else if ( CurrentPlayer == PLAYER_BLACK ) { if ( CheckCellState( REALH(ONE), REALV(EIGHT), WHITE, aReversiTable ) ) { if ( ( CheckCellState( REALH(ONE), REALV(SEVEN), BLACK, aReversiTable ) ) || ( CheckCellState( REALH(TWO), REALV(EIGHT), BLACK, aReversiTable ) ) ) { pDiscInfo->EdgeOfSouthWest = SUCCESS; } } } } /* 北西角 */ pDiscInfo->EdgeOfNorthWest = ERROR; if ( ((RealH == ONE) && (RealV == REALV(TWO))) || ((RealH == TWO) && (RealV == REALV(ONE))) ) { /* 白のターン */ if ( CurrentPlayer == PLAYER_WHITE ) { if ( CheckCellState( REALH(ONE), REALV(ONE), BLACK, aReversiTable ) ) { if ( ( CheckCellState( REALH(ONE), REALV(TWO), WHITE, aReversiTable ) ) || ( CheckCellState( REALH(TWO), REALV(ONE), WHITE, aReversiTable ) ) ) { pDiscInfo->EdgeOfNorthWest = SUCCESS; } } /* 黒のターン */ } else if ( CurrentPlayer == PLAYER_BLACK ) { if ( CheckCellState( REALH(ONE), REALV(ONE), WHITE, aReversiTable ) ) { if ( ( CheckCellState( REALH(ONE), REALV(TWO), BLACK, aReversiTable ) ) || ( CheckCellState( REALH(TWO), REALV(ONE), BLACK, aReversiTable ) ) ) { pDiscInfo->EdgeOfNorthWest = SUCCESS; } } } } }
static Const fold_op(Node node) /*;fold_op*/ { Node opn, arg1, arg2, oplist; Const result, op1, op2, tryc; Symbol sym, op_name; int *uint; int rm; Tuple tup; int res, overflow; opn = N_AST1(node); oplist = N_AST2(node); tup = N_LIST(oplist); arg1 = (Node) tup[1]; arg2 = (Node) tup[2]; op1 = const_fold(arg1); op2 = const_fold(arg2); op_name = N_UNQ(opn); /* If either operand raises and exception, so does the operation */ if (N_KIND(arg1) == as_raise) { copy_attributes(arg1, node); return const_new(CONST_OM); } if (N_KIND(arg2) == as_raise && op_name != symbol_andthen && op_name != symbol_orelse) { copy_attributes(arg2, node); return const_new(CONST_OM); } if (is_const_om(op1) || (is_const_om(op2) && (op_name != symbol_in || op_name != symbol_notin))) { return const_new(CONST_OM); } sym = op_name; if ( sym == symbol_addi || sym == symbol_addfl) { if (sym == symbol_addi) { res = word_add(INTV(op1), INTV(op2), &overflow); if (overflow) { create_raise(node, symbol_constraint_error); result = const_new(CONST_OM); } else result = int_const(res); } else result = real_const(REALV(op1) + REALV(op2)); } else if ( sym == symbol_addfx) { const_check(op1, CONST_RAT); const_check(op2, CONST_RAT); result= rat_const(rat_add(RATV(op1), RATV(op2))); } else if ( sym == symbol_subi) { if (is_const_int(op1)) { if (is_const_int(op2)) { res = word_sub(INTV(op1), INTV(op2), &overflow); if (overflow) { create_raise(node, symbol_constraint_error); result = const_new(CONST_OM); } else result = int_const(res); } else { chaos("fold_op: subi operand types"); } } } else if (sym == symbol_subfl) { result = real_const(REALV(op1) - REALV(op2)); } else if ( sym == symbol_subfx) { const_check(op1, CONST_RAT); const_check(op2, CONST_RAT); result= rat_const(rat_sub(RATV(op1), RATV(op2))); } else if ( sym == symbol_muli) { #ifdef TBSL -- need to check for overflow and convert result back to int if not -- note that low-level setl is missing calls to check_overflow that -- are present in high-level and should be in low-level as well result = int_mul(int_fri(op1), int_fri(op2)); #endif /* until overflow check in */ const_check(op1, CONST_INT); const_check(op2, CONST_INT); res = word_mul(INTV(op1), INTV(op2), &overflow); if (overflow) { create_raise(node, symbol_constraint_error); result = const_new(CONST_OM); } else result = int_const(res); }
static Const fold_unop(Node node) /*;fold_unop*/ { Node opn, oplist; Const result, op1; int op1_kind; Symbol sym; opn = N_AST1(node); oplist = N_AST2(node); op1 = const_fold((Node) (N_LIST(oplist))[1]); if (is_const_om(op1)) return op1; op1_kind = op1->const_kind; sym = N_UNQ(opn); if (sym == symbol_addui) { /* the "+" can be ignored if it is used as a unary op */ result = op1; } else if (sym == symbol_addufl) { result = op1; } else if (sym == symbol_addufx) { result = op1; } else if (sym == symbol_subui || sym == symbol_subufl || sym == symbol_subufx) { if (is_simple_value(op1)) { if (sym == symbol_subui) { if (is_const_int(op1)) { if (INTV(op1) == ADA_MIN_INTEGER) { create_raise(node, symbol_constraint_error); result = const_new(CONST_OM); } else { result = int_const(-INTV(op1)); } } else if (is_const_uint(op1)) result = uint_const(int_umin(UINTV(op1))); else chaos("eval:subui bad type"); } else if (sym == symbol_subufl) { const_check(op1, CONST_REAL); result = real_const(-REALV(op1)); } } else { const_check(op1, CONST_RAT); result= rat_const(rat_umin(RATV(op1))); } } else if ( sym == symbol_not) { if (is_simple_value (op1)) { if (op1_kind == CONST_INT) result = int_const(1-INTV(op1)); /*bnot in setl */ else chaos("fold_unop: bad kind"); } else { /*TBSL*/ result = const_new(CONST_OM); } } else if ( sym == symbol_absi || sym == symbol_absfl || sym == symbol_absfx) { if (is_simple_value(op1)) { if (sym == symbol_absi) { if (op1_kind == CONST_INT) result = int_const(abs(INTV(op1))); else if (op1_kind == CONST_UINT)chaos("fold_unit absi in uint"); else chaos("fold_unop: bad kind"); } else if (sym == symbol_absfl) { result = real_const(fabs(REALV(op1))); } } else { result= rat_const(rat_abs(RATV(op1))); } } return result; }