void draw_planet(HDC hDC, planetstruct *planet) { HBRUSH hbrColor, hbrOld; gravstruct *gp = &gravs; double D; // a DX variable to work with unsigned char cmpt; D = POS(X) * POS(X) + POS(Y) * POS(Y) + POS(Z) * POS(Z); if (D < COLLIDE) D = COLLIDE; D = sqrt(D); D = D * D * D; for (cmpt = X; cmpt < DIMENSIONS; cmpt++) { ACC(cmpt) = POS(cmpt) * GRAV / D; if (iDamping) { if (ACC(cmpt) > MaxA) ACC(cmpt) = MaxA; else if (ACC(cmpt) < -MaxA) ACC(cmpt) = -MaxA; VEL(cmpt) = VEL(cmpt) + ACC(cmpt); VEL(cmpt) *= DAMP; } else { // update velocity VEL(cmpt) = VEL(cmpt) + ACC(cmpt); } // update position POS(cmpt) = POS(cmpt) + VEL(cmpt); } gp->x = planet->xi; gp->y = planet->yi; if (POS(Z) > -ALMOST) { planet->xi = (unsigned int) ((double) gp->width * (HALF + POS(X) / (POS(Z) + DIST))); planet->yi = (unsigned int) ((double) gp->height * (HALF + POS(Y) / (POS(Z) + DIST))); } else planet->xi = planet->yi = -1; // Mask hbrOld = (HBRUSH)SelectObject(hDC, (HBRUSH)GetStockObject(BLACK_BRUSH)); Planet(gp->x, gp->y); if (iTrails) SetPixel(hDC, gp->x, gp->y, PALETTEINDEX(100)); // Move gp->x = planet->xi; gp->y = planet->yi; planet->ri = RADIUS; if (iColorCycle) { if (planet->colors++ > (PALSIZE-21)) planet->colors = 1; } // Redraw hbrColor = CreateSolidBrush(PALETTEINDEX(planet->colors)); SelectObject(hDC, hbrColor); Planet(gp->x, gp->y); SelectObject(hDC, hbrOld); DeleteObject(hbrColor); }
bool chain::evaluating_chain(int black_live_eye_arr[], int white_live_eye_arr[]) { this->live = 0; list<stone*> try_position; int forbid = 0; int forbiden[5] = {-1,-1,-1,-1,-1}; int S[BOARD_SIZE*BOARD_SIZE]; for (int i = 0; i < BOARD_SIZE*BOARD_SIZE; i++) S[i] = 0; for (std::list<stone*>::iterator itor = this->stones.begin(); itor != this->stones.end(); ++itor) { for (int i = 0; i < 4; i++) { int row = (*itor)->row + deltai[i]; int col = (*itor)->col + deltaj[i]; int index = POS(row,col); stone* curr = chain_block->block_board->main_board[index]; if (chain_block->block_board->on_board(row, col)) { if (curr->color == EMPTY) { if (S[index] != 0) continue; S[index] = 1; curr->color = OTHER_COLOR(chain_block->color); if (curr->eat_this_chain(this)) { try_position.push_back(curr); std::list<stone*>::iterator itor2 = try_position.begin(); while (itor2 != try_position.end()) { if (chain_block->color == BLACK){ black_live_eye_arr[POS((*itor2)->row, (*itor2)->col)] = 1; //try_position不是白棋的真眼 } else{ white_live_eye_arr[POS((*itor2)->row, (*itor2)->col)] = 1; //try_position不是黑棋的真眼 } (*itor2)->color = EMPTY; try_position.erase(itor2++); } this->live = 0; return 1; } else if (curr->can_live(this)) { try_position.push_back(curr); } else //Neither to eat this chain nor to live { curr->color = EMPTY; S[index] = 2; } } } } } int count = 0; for (int i = 0; i < BOARD_SIZE*BOARD_SIZE; i++){ if (S[i] == 2) count++; } if (count < 2) { //S[i]周围不能是live eye for (int i = 0; i < BOARD_SIZE*BOARD_SIZE; i++){ if (S[i] == 2) { if (chain_block->color == BLACK){ black_live_eye_arr[i] = 1; //try_position不是白棋的真眼 } else{ white_live_eye_arr[i] = 1; //try_position不是黑棋的真眼 } queue<int> q; q.push(i); not_live_eye_bfs(this, OTHER_COLOR(this->chain_block->color), q, black_live_eye_arr, white_live_eye_arr); } } std::list<stone*>::iterator itor2 = try_position.begin(); while (itor2 != try_position.end()) { if (chain_block->color == BLACK){ black_live_eye_arr[POS((*itor2)->row, (*itor2)->col)] = 1; //try_position不是白棋的真眼 } else{ white_live_eye_arr[POS((*itor2)->row, (*itor2)->col)] = 1; //try_position不是黑棋的真眼 } (*itor2)->color = EMPTY; try_position.erase(itor2++); } this->live = 0; } else { for (int i = 0; i < BOARD_SIZE*BOARD_SIZE; i++){ if (S[i] == 2) { if (chain_block->color == BLACK){ if (black_live_eye_arr[i] != 1) black_live_eye_arr[i] = 2; //可能是白棋的真眼 } else{ if (white_live_eye_arr[i] != 1) white_live_eye_arr[i] = 2; //可能是黑棋的真眼 } queue<int> q; q.push(i); live_eye_bfs(this, OTHER_COLOR(this->chain_block->color), q, black_live_eye_arr, white_live_eye_arr); } } this->live = 1; } std::list<stone*>::iterator itor = try_position.begin(); while (itor != try_position.end()) { (*itor)->color = EMPTY; try_position.erase(itor++); } return 1; }
int pegue_palitos(struct jogad jogador[] , int num, int rodadas, int total_palitos ) { int i; int palitos; do { // pegar a quantidade de palitos do jogador humano // posicao inicial das mensagens i=18; JANELA2(); POS (i++,5); printf ("Você possui [%d] palitos, há [%2d] palitos em jogo", jogador[0].tpalitos, total_palitos); POS (i++,5); printf ("Jogador, digite quantos palitos quer jogar, para sair [-1]: "); // muda palitos antes do condicional, // isto previne sair do programa quando palitos == -1 scanf("%d", &palitos); // caso se escolha -1, isto eh sair do jogo if ( palitos == -1) { tela_saida(); //mostra tela de saída exit(0); //saí do jogo } if ( (palitos < 0) || ( palitos > jogador[0].tpalitos) ) { STATUS(); printf("Quantidade inválida de palitos"); } ;; if ((rodadas == 1) && (palitos == 0)) { STATUS(); printf("Na primeira rodada a quantidade de palitos deve ser maior que 0"); palitos= -1; // para não sair no laço pois continue não funcionou } ;; } while ( (palitos < 0) || ( palitos > jogador[0].tpalitos) ); ;; jogador[0].palitos = palitos; for (i = 1; i < num + 1; i++) { // gera um numero de palitos a jogar por numeros aleatorios // inteligencia=0. jogador[i].palitos = aleatorio(jogador[i].tpalitos); if ((rodadas == 1) && (jogador[i].palitos == 0)) i--; // decrementa i para permanecer no mesmo jogador ;; } ;; palitos = 0; for (i = 0; i <= num ; i++) palitos += jogador[i].palitos; //total de palitos ;; return(palitos); }
/* Play at (i, j) for color. No legality check is done here. We need * to properly update the board array, the next_stone array, and the * ko point. */ static void play_move(int i, int j, int color) { int pos = POS(i, j); int captured_stones = 0; int k; /* Reset the ko point. */ ko_i = -1; ko_j = -1; /* Nothing more happens if the move was a pass. */ if (pass_move(i, j)) return; /* If the move is a suicide we only need to remove the adjacent * friendly stones. */ if (suicide(i, j, color)) { for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == color) remove_string(ai, aj); } return; } /* Not suicide. Remove captured opponent strings. */ for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == OTHER_COLOR(color) && !has_additional_liberty(ai, aj, i, j)) captured_stones += remove_string(ai, aj); } /* Put down the new stone. Initially build a single stone string by * setting next_stone[pos] pointing to itself. */ board[pos] = color; next_stone[pos] = pos; /* If we have friendly neighbor strings we need to link the strings * together. */ for (k = 0; k < 4; k++) { int ai = i + deltai[k]; int aj = j + deltaj[k]; int pos2 = POS(ai, aj); /* Make sure that the stones are not already linked together. This * may happen if the same string neighbors the new stone in more * than one direction. */ if (on_board(ai, aj) && board[pos2] == color && !same_string(pos, pos2)) { /* The strings are linked together simply by swapping the the * next_stone pointers. */ int tmp = next_stone[pos2]; next_stone[pos2] = next_stone[pos]; next_stone[pos] = tmp; } } /* If we have captured exactly one stone and the new string is a * single stone it may have been a ko capture. */ if (captured_stones == 1 && next_stone[pos] == pos) { int ai, aj; /* Check whether the new string has exactly one liberty. If so it * would be an illegal ko capture to play there immediately. We * know that there must be a liberty immediately adjacent to the * new stone since we captured one stone. */ for (k = 0; k < 4; k++) { ai = i + deltai[k]; aj = j + deltaj[k]; if (on_board(ai, aj) && get_board(ai, aj) == EMPTY) break; } if (!has_additional_liberty(i, j, ai, aj)) { ko_i = ai; ko_j = aj; } } }
int SubOverflow (ARMword a, ARMword b, ARMword result) { return ((NEG (a) && POS (b) && POS (result)) || (POS (a) && NEG (b) && NEG (result))); }
//----------------------------------------------------------------------------------------------- void CRenderCamera::GetPos ( tVect3& vOutPos )const { vOutPos = POS(m_TM); }
static av_always_inline void FUNC(intra_pred)(HEVCContext *s, int x0, int y0, int log2_size, int c_idx) { #define PU(x) \ ((x) >> s->sps->log2_min_pu_size) #define MVF(x, y) \ (s->ref->tab_mvf[(x) + (y) * min_pu_width]) #define MVF_PU(x, y) \ MVF(PU(x0 + ((x) << hshift)), PU(y0 + ((y) << vshift))) #define IS_INTRA(x, y) \ (MVF_PU(x, y).pred_flag == PF_INTRA) #define MIN_TB_ADDR_ZS(x, y) \ s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)] #define EXTEND(ptr, val, len) \ do { \ pixel4 pix = PIXEL_SPLAT_X4(val); \ for (i = 0; i < (len); i += 4) \ AV_WN4P(ptr + i, pix); \ } while (0) #define EXTEND_RIGHT_CIP(ptr, start, length) \ for (i = start; i < (start) + (length); i += 4) \ if (!IS_INTRA(i, -1)) \ AV_WN4P(&ptr[i], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i+3]) #define EXTEND_LEFT_CIP(ptr, start, length) \ for (i = start; i > (start) - (length); i--) \ if (!IS_INTRA(i - 1, -1)) \ ptr[i - 1] = ptr[i] #define EXTEND_UP_CIP(ptr, start, length) \ for (i = (start); i > (start) - (length); i -= 4) \ if (!IS_INTRA(-1, i - 3)) \ AV_WN4P(&ptr[i - 3], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i - 3]) #define EXTEND_DOWN_CIP(ptr, start, length) \ for (i = start; i < (start) + (length); i += 4) \ if (!IS_INTRA(-1, i)) \ AV_WN4P(&ptr[i], a); \ else \ a = PIXEL_SPLAT_X4(ptr[i + 3]) HEVCLocalContext *lc = s->HEVClc; int i; int hshift = s->sps->hshift[c_idx]; int vshift = s->sps->vshift[c_idx]; int size = (1 << log2_size); int size_in_luma_h = size << hshift; int size_in_tbs_h = size_in_luma_h >> s->sps->log2_min_tb_size; int size_in_luma_v = size << vshift; int size_in_tbs_v = size_in_luma_v >> s->sps->log2_min_tb_size; int x = x0 >> hshift; int y = y0 >> vshift; int x_tb = x0 >> s->sps->log2_min_tb_size; int y_tb = y0 >> s->sps->log2_min_tb_size; int cur_tb_addr = MIN_TB_ADDR_ZS(x_tb, y_tb); ptrdiff_t stride = s->frame->linesize[c_idx] / sizeof(pixel); pixel *src = (pixel*)s->frame->data[c_idx] + x + y * stride; int min_pu_width = s->sps->min_pu_width; enum IntraPredMode mode = c_idx ? lc->tu.cur_intra_pred_mode_c : lc->tu.cur_intra_pred_mode; pixel4 a; pixel left_array[2 * MAX_TB_SIZE + 1]; pixel filtered_left_array[2 * MAX_TB_SIZE + 1]; pixel top_array[2 * MAX_TB_SIZE + 1]; pixel filtered_top_array[2 * MAX_TB_SIZE + 1]; pixel *left = left_array + 1; pixel *top = top_array + 1; pixel *filtered_left = filtered_left_array + 1; pixel *filtered_top = filtered_top_array + 1; int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb - 1, y_tb + size_in_tbs_v); int cand_left = lc->na.cand_left; int cand_up_left = lc->na.cand_up_left; int cand_up = lc->na.cand_up; int cand_up_right = lc->na.cand_up_right && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb + size_in_tbs_h, y_tb - 1); int bottom_left_size = (FFMIN(y0 + 2 * size_in_luma_v, s->sps->height) - (y0 + size_in_luma_v)) >> vshift; int top_right_size = (FFMIN(x0 + 2 * size_in_luma_h, s->sps->width) - (x0 + size_in_luma_h)) >> hshift; if (s->pps->constrained_intra_pred_flag == 1) { int size_in_luma_pu_v = PU(size_in_luma_v); int size_in_luma_pu_h = PU(size_in_luma_h); int on_pu_edge_x = !(x0 & ((1 << s->sps->log2_min_pu_size) - 1)); int on_pu_edge_y = !(y0 & ((1 << s->sps->log2_min_pu_size) - 1)); if (!size_in_luma_pu_h) size_in_luma_pu_h++; if (cand_bottom_left == 1 && on_pu_edge_x) { int x_left_pu = PU(x0 - 1); int y_bottom_pu = PU(y0 + size_in_luma_v); int max = FFMIN(size_in_luma_pu_v, s->sps->min_pu_height - y_bottom_pu); cand_bottom_left = 0; for (i = 0; i < max; i += 2) cand_bottom_left |= (MVF(x_left_pu, y_bottom_pu + i).pred_flag == PF_INTRA); } if (cand_left == 1 && on_pu_edge_x) { int x_left_pu = PU(x0 - 1); int y_left_pu = PU(y0); int max = FFMIN(size_in_luma_pu_v, s->sps->min_pu_height - y_left_pu); cand_left = 0; for (i = 0; i < max; i += 2) cand_left |= (MVF(x_left_pu, y_left_pu + i).pred_flag == PF_INTRA); } if (cand_up_left == 1) { int x_left_pu = PU(x0 - 1); int y_top_pu = PU(y0 - 1); cand_up_left = MVF(x_left_pu, y_top_pu).pred_flag == PF_INTRA; } if (cand_up == 1 && on_pu_edge_y) { int x_top_pu = PU(x0); int y_top_pu = PU(y0 - 1); int max = FFMIN(size_in_luma_pu_h, s->sps->min_pu_width - x_top_pu); cand_up = 0; for (i = 0; i < max; i += 2) cand_up |= (MVF(x_top_pu + i, y_top_pu).pred_flag == PF_INTRA); } if (cand_up_right == 1 && on_pu_edge_y) { int y_top_pu = PU(y0 - 1); int x_right_pu = PU(x0 + size_in_luma_h); int max = FFMIN(size_in_luma_pu_h, s->sps->min_pu_width - x_right_pu); cand_up_right = 0; for (i = 0; i < max; i += 2) cand_up_right |= (MVF(x_right_pu + i, y_top_pu).pred_flag == PF_INTRA); } memset(left, 128, 2 * MAX_TB_SIZE*sizeof(pixel)); memset(top , 128, 2 * MAX_TB_SIZE*sizeof(pixel)); top[-1] = 128; } if (cand_up_left) { left[-1] = POS(-1, -1); top[-1] = left[-1]; } if (cand_up) memcpy(top, src - stride, size * sizeof(pixel)); if (cand_up_right) { memcpy(top + size, src - stride + size, size * sizeof(pixel)); EXTEND(top + size + top_right_size, POS(size + top_right_size - 1, -1), size - top_right_size); } if (cand_left) for (i = 0; i < size; i++) left[i] = POS(-1, i); if (cand_bottom_left) { for (i = size; i < size + bottom_left_size; i++) left[i] = POS(-1, i); EXTEND(left + size + bottom_left_size, POS(-1, size + bottom_left_size - 1), size - bottom_left_size); } if (s->pps->constrained_intra_pred_flag == 1) { if (cand_bottom_left || cand_left || cand_up_left || cand_up || cand_up_right) { int size_max_x = x0 + ((2 * size) << hshift) < s->sps->width ? 2 * size : (s->sps->width - x0) >> hshift; int size_max_y = y0 + ((2 * size) << vshift) < s->sps->height ? 2 * size : (s->sps->height - y0) >> vshift; int j = size + (cand_bottom_left? bottom_left_size: 0) -1; if (!cand_up_right) { size_max_x = x0 + ((size) << hshift) < s->sps->width ? size : (s->sps->width - x0) >> hshift; } if (!cand_bottom_left) { size_max_y = y0 + (( size) << vshift) < s->sps->height ? size : (s->sps->height - y0) >> vshift; }
int compute_surroundings(int pos, int apos, int showboard, int *surround_size) { int i, j; int m, n; int k; int dpos; int surrounded; int left_corner[MAX_BOARD]; int right_corner[MAX_BOARD]; int corner[BOARDMAX]; int left_corners = 0, right_corners = 0; int corners = 0; int top_row, bottom_row; int color = board[pos]; int other = OTHER_COLOR(color); int gi = 0; int gj = 0; int stones = 0; int found_some; char mf[BOARDMAX]; /* friendly dragon */ char mn[BOARDMAX]; /* neighbor dragons */ int sd[BOARDMAX]; /* distances to the goal */ if (DRAGON2(pos).hostile_neighbors == 0) return(0); memset(mf, 0, sizeof(mf)); memset(mn, 0, sizeof(mn)); memset(sd, 0, sizeof(sd)); mark_dragon(pos, mf, 1); /* mark hostile neighbors */ for (k = 0; k < DRAGON2(pos).neighbors; k++) { int nd = DRAGON(DRAGON2(pos).adjacent[k]).origin; if (board[nd] != color) { if (0) gprintf("neighbor: %1m\n", nd); mark_dragon(nd, mn, 1); } } /* descend markings from stones lying on the 2nd and third lines */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mn[dpos]) { for (k = 0; k < 4; k++) { int d = delta[k]; if (!ON_BOARD(dpos + d)) continue; if (!ON_BOARD(dpos + 2*d)) { if (board[dpos + d] == EMPTY) mn[dpos + d] = 1; } else if (!ON_BOARD(dpos + 3*d)) { if (board[dpos + d] == EMPTY && board[dpos + 2*d] == EMPTY) mn[dpos + 2*d] = 1; } } } /* compute minimum distances to the goal */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mn[dpos]) sd[dpos] = goal_dist(dpos, mf); /* revise markings */ do { found_some = 0; for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mn[dpos] && sd[dpos] > 8) { /* discard markings if we can find 2 stones * that verify : * - it is closer to the goal than we are * - it is closer to us than the goal is * - they are closer to each other than we are to the goal */ for (i = BOARDMIN; i < BOARDMAX; i++) if (ON_BOARD(i) && mn[i] && i != dpos && sd[i] < sd[dpos] && square_dist(i, dpos) < sd[dpos]) { for (j = i + 1; j < BOARDMAX; j++) if (ON_BOARD(j) && mn[j] && j != dpos && sd[j] < sd[dpos] && square_dist(j, dpos) < sd[dpos] && square_dist(i, j) < sd[dpos]) { mn[dpos] = 0; found_some = 1; break; } if (mn[dpos] == 0) break; } } } while (found_some); /* prepare corner array */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mn[dpos]) corner[corners++] = dpos; /* compute gravity center of the goal */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mf[dpos]) { gi += I(dpos); gj += J(dpos); stones++; } gi /= stones; gj /= stones; gg = POS(gi, gj); /* sort the corner array */ gg_sort(corner, corners, sizeof(int), compare_angles); /* if apos is not NO_MOVE, mark it. */ if (apos != NO_MOVE) { ASSERT_ON_BOARD1(apos); mn[apos] = 1; } if (showboard == 1) { show_surround_map(mf, mn); } /* find top row of surrounding polyhedron */ top_row = -1; for (m = 0; m < board_size; m++) { if (top_row != -1) break; for (n = 0; n < board_size; n++) if (mn[POS(m, n)]) { left_corner[0] = POS(m, n); top_row = m; break; } } /* find bottom row */ bottom_row = -1; for (m = board_size - 1; m >= 0; m--) { if (bottom_row != -1) break; for (n = 0; n < board_size; n++) if (mn[POS(m, n)]) { bottom_row = m; break; } } /* find the corners on the left side */ for (left_corners = 1; I(left_corner[left_corners-1]) < bottom_row; left_corners++) { int best_found = 0; float best_slope = 0.; int m = I(left_corner[left_corners-1]); int n = J(left_corner[left_corners-1]); for (i = m + 1; i <= bottom_row; i++) for (j = 0; j < board_size; j++) if (mn[POS(i, j)]) { float slope = ((float) (j - n))/((float) (i - m)); if (0) gprintf("(left) at %m, last %m, slope=%f\n", i, j, m, n, slope); if (!best_found || slope < best_slope) { best_found = POS(i, j); best_slope = slope; } } ASSERT_ON_BOARD1(best_found); left_corner[left_corners] = best_found; } for (n = board_size-1; n >= 0; n--) if (mn[POS(top_row, n)]) { right_corner[0] = POS(top_row, n); break; } /* find the corners on the right side */ for (right_corners = 1; I(right_corner[right_corners-1]) < bottom_row; right_corners++) { int best_found = 0; float best_slope = 0.; int m = I(right_corner[right_corners-1]); int n = J(right_corner[right_corners-1]); for (i = m + 1; i <= bottom_row; i++) { for (j = board_size - 1; j >= 0; j--) { if (mn[POS(i, j)]) { float slope = ((float) (j - n))/((float) (i - m)); if (0) gprintf("(right) at %m, last %m, slope=%f\n", i, j, m, n, slope); if (!best_found || slope > best_slope) { best_found = POS(i, j); best_slope = slope; } } } } ASSERT_ON_BOARD1(best_found); right_corner[right_corners] = best_found; } if (0) { for (k = 0; k < left_corners; k++) gprintf("left corner %d: %1m\n", k, left_corner[k]); for (k = 0; k < right_corners; k++) gprintf("right corner %d: %1m\n", k, right_corner[k]); } /* Now mark the interior of the convex hull */ for (n = J(left_corner[0]); n <= J(right_corner[0]); n++) mn[POS(top_row, n)] = 1; for (n = J(left_corner[left_corners-1]); n <= J(right_corner[right_corners-1]); n++) mn[POS(bottom_row, n)] = 1; for (m = top_row+1; m < bottom_row; m++) { int left_boundary = -1, right_boundary = -1; for (k = 1; k < left_corners; k++) { if (I(left_corner[k]) > m) { float ti = I(left_corner[k-1]); float tj = J(left_corner[k-1]); float bi = I(left_corner[k]); float bj = J(left_corner[k]); if (0) gprintf("(left) %d: %1m %1m\n", m, left_corner[k-1], left_corner[k]); /* left edge in this row is on segment (ti,tj) -> (bi, bj) */ /* FIXME: Rewrite this to avoid floating point arithmetic */ left_boundary = ceil(tj + (m - ti) * (bj - tj) / (bi - ti)); break; } } for (k = 1; k < right_corners; k++) { if (I(right_corner[k]) > m) { float ti = I(right_corner[k-1]); float tj = J(right_corner[k-1]); float bi = I(right_corner[k]); float bj = J(right_corner[k]); if (0) gprintf("(right) %d: %1m %1m\n", m, right_corner[k-1], right_corner[k]); /* FIXME: Rewrite this to avoid floating point arithmetic */ right_boundary = floor(tj + (m - ti) * (bj - tj) / (bi - ti)); break; } } for (n = left_boundary; n <= right_boundary; n++) mn[POS(m, n)] = 1; } /* mark the expanded region */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) if (ON_BOARD(dpos) && mn[dpos] == 1) for (k = 0; k < 4; k++) if (ON_BOARD(dpos + delta[k]) && !mn[dpos + delta[k]]) mn[dpos + delta[k]] = 2; /* Mark allied dragons that intersect the (unexpanded) hull. * These must all lie entirely within the hull for the * dragon to be considered surrounded. * * Only neighbor dragons are considered since dragons that * are not neighbors are less likely to be helpful. */ for (dpos = BOARDMIN; dpos < BOARDMAX; dpos++) { int mpos; if (ON_BOARD(dpos) && mn[dpos] == 1 && board[dpos] == color && are_neighbor_dragons(pos, dpos) && !mf[dpos]) { for (mpos = BOARDMIN; mpos < BOARDMAX; mpos++) if (ON_BOARD(mpos) && is_same_dragon(mpos, dpos)) mf[mpos] = 2; } /* A special case * * . X X . * X O . X * X . O O * . O . . * * The O stone hasn't been amalgamated and the surround computations * might think this single stone dragon is surrounded, which in turn * can generate overvaluation of moves around this stone. * Consequently, we allow inclusion of the stones at kosumi distance * in the mf (friendly) array. */ if (ON_BOARD(dpos) && mn[dpos] == 2 && board[dpos] == color && are_neighbor_dragons(pos, dpos) && !mf[dpos]) { for (k = 4; k < 8; k++) if (ON_BOARD(dpos + delta[k]) && board[dpos + delta[k]] == color && mn[dpos + delta[k]] == 1 && board[dpos + delta[k-4]] == EMPTY && board[dpos + delta[(k-3)%4]] == EMPTY) { for (mpos = BOARDMIN; mpos < BOARDMAX; mpos++) if (ON_BOARD(mpos) && is_same_dragon(mpos, dpos)) mf[mpos] = 2; } } } /* determine the surround status of the dragon */ surrounded = SURROUNDED; /* Compute the maximum surround status awarded * If distances between enclosing stones are large, reduce to * WEAKLY_SURROUNDED. If (really) too large, then reduce to 0 * FIXME: constants chosen completely ad hoc. Possibly better tunings * can be found. */ for (k = 0; k < corners - 1; k++) { if (is_edge_vertex(corner[k]) && is_edge_vertex(corner[k+1])) continue; if (square_dist(corner[k], corner[k+1]) > 60) { surrounded = 0; break; } else if (square_dist(corner[k], corner[k+1]) > 27) surrounded = WEAKLY_SURROUNDED; } if (surrounded && (!is_edge_vertex(corner[0]) || !is_edge_vertex(corner[corners-1]))) { if (square_dist(corner[0], corner[corners-1]) > 60) surrounded = 0; else if (square_dist(corner[0], corner[corners-1]) > 27) surrounded = WEAKLY_SURROUNDED; } if (surrounded) for (m = 0; m < board_size; m++) for (n = 0; n < board_size; n++) { if (mf[POS(m, n)]) { if (mn[POS(m, n)] == 0) { surrounded = 0; break; } else if (mn[POS(m, n)] == 2) surrounded = WEAKLY_SURROUNDED; } } /* revise the status for single stone dragons. */ if (stones == 1 && surrounded == WEAKLY_SURROUNDED && mn[pos] == 2) surrounded = 0; /* revise the status if an ikken tobi jumps out. */ if (surrounded) { for (dpos = BOARDMIN; dpos < BOARDMAX && surrounded; dpos++) { if (!ON_BOARD(dpos) || !mf[dpos]) continue; for (k = 0; k < 4; k++) { int up = delta[k]; int right = delta[(k + 1) % 4]; if (board[dpos + up] == EMPTY && board[dpos + 2*up] == color && mn[dpos + 2*up] != 1 && ON_BOARD(dpos + up + right) && board[dpos + up + right] != other && ON_BOARD(dpos + up - right) && board[dpos + up - right] != other) { surrounded = 0; break; } } } } if (showboard == 1 || (showboard == 2 && surrounded)) { show_surround_map(mf, mn); } if (!apos && surrounded && surround_pointer < MAX_SURROUND) { memcpy(surroundings[surround_pointer].surround_map, mn, sizeof(mn)); surroundings[surround_pointer].dragon_number = dragon[pos].id; surround_pointer++; } if (surround_size) { int pos; *surround_size = 0; for (pos = BOARDMIN; pos < BOARDMAX; pos++) if (ON_BOARD(pos) && mn[pos] == 1) (*surround_size)++; } return surrounded; }
static inline void set_hchar(struct part *p, int x, int y, unsigned c) { xpand_lines(p, y); xpand_line(p, y, x); POS(x, y) = c; }
/** * Create the adjacency list for each position on the board. An example of the * board for size of 15 is shown below. The edges are created for a position in * a clockwise manner. * *---*---*---*---* * |0 |1 |2 |3 | * *---*---*---*---* * |4 |5 |6 |7 | * *---*---*---*---* * |8 |9 |10 |11 | * *---*---*---*---* * |12 |13 |14 |15 | * *---*---*---*---* * @param row * @param col */ void GemPuzzleState::MakeEdges(int row, int col,vector<int>& list) { if (row == 0) { if (col == 0) { list.push_back(POS((row), (col + 1), _dim)); list.push_back(POS((row + 1), (col), _dim)); } else if (col == _dim - 1) { list.push_back(POS((row + 1), (col), _dim)); list.push_back(POS((row), (col - 1), _dim)); } else { list.push_back(POS(row, (col + 1), _dim)); list.push_back(POS((row + 1), col, _dim)); list.push_back(POS(row, (col - 1), _dim)); } } else if (row == _dim - 1) { if (col == 0) { list.push_back(POS((row-1), (col), _dim)); list.push_back(POS((row), (col+1), _dim)); } else if (col == _dim - 1) { list.push_back(POS((row), (col-1), _dim)); list.push_back(POS((row-1), (col), _dim)); } else { list.push_back(POS((row), (col-1), _dim)); list.push_back(POS((row-1), (col), _dim)); list.push_back(POS((row), (col+1), _dim)); } } else { if (col == 0) { list.push_back(POS((row-1), (col), _dim)); list.push_back(POS((row), (col+1), _dim)); list.push_back(POS((row+1), (col), _dim)); } else if (col == _dim - 1) { list.push_back(POS((row+1), (col), _dim)); list.push_back(POS((row), (col-1), _dim)); list.push_back(POS((row-1), (col), _dim)); } else { list.push_back(POS((row-1), (col), _dim)); list.push_back(POS((row), (col+1), _dim)); list.push_back(POS((row+1), (col), _dim)); list.push_back(POS((row), (col-1), _dim)); } } }
pweibo_user weibo_user_create_json(json_t* pJson) { if (!pJson) { PERR("could not parse json!\n"); return NULL; } void *iter = json_object_iter(pJson); pweibo_user pUser = weibo_user_init(); while (iter) { const char* key = json_object_iter_key(iter); //DEBUG("%s\n", key); json_t *value = json_object_iter_value(iter); if(!value) { iter = json_object_iter_next(pJson, iter); continue; } //DEBUG("%d\n", value->type); if (0 == strcmp("id", key)) { pUser->m_szID = g_string_new(""); g_string_printf(pUser->m_szID, "%"JSON_INTEGER_FORMAT, json_integer_value(value)); } else if (0 == strcmp("screen_name", key)) { pUser->m_szScreenName = g_string_new(json_string_value(value)); } else if (0 == strcmp("name", key)) { pUser->m_szName = g_string_new(json_string_value(value)); } else if (0 == strcmp("province", key)) { pUser->m_nProvince = json_integer_value(value); } else if (0 == strcmp("city", key)) { pUser->m_nCity = json_integer_value(value); } else if (0 == strcmp("location", key)) { pUser->m_szLocation = g_string_new(json_string_value(value)); } else if (0 == strcmp("description", key)) { pUser->m_szDescription = g_string_new(json_string_value(value)); } else if (0 == strcmp("url", key)) { pUser->m_szUrl = g_string_new(json_string_value(value)); } else if (0 == strcmp("profile_image_url", key)) { pUser->m_szProfileImageUrl = g_string_new(json_string_value(value)); } else if (0 == strcmp("domain", key)) { pUser->m_szDomain = g_string_new(json_string_value(value)); } else if (0 == strcmp("gender", key)) { pUser->m_szGender = g_string_new(json_string_value(value)); } else if (0 == strcmp("followers_count", key)) { pUser->m_nFollowersCount = json_integer_value(value); } else if (0 == strcmp("friends_count", key)) { pUser->m_nFriendsCount = json_integer_value(value); } else if (0 == strcmp("statuses_count", key)) { pUser->m_nStatusesCount = json_integer_value(value); } else if (0 == strcmp("favourites_count", key)) { pUser->m_nFavouritesCount = json_integer_value(value); } else if (0 == strcmp("created_at", key)) { pUser->m_szCreatedAt = g_string_new(json_string_value(value)); } else if (0 == strcmp("following", key)) { pUser->m_bFollowing = json_is_true(value) ? TRUE : FALSE; } else if (0 == strcmp("allow_all_act_msg", key)) { pUser->m_bAllowAllActMsg = json_is_true(value) ? TRUE : FALSE; } else if (0 == strcmp("geo_enabled", key)) { pUser->m_bGeoEnabled = json_is_true(value) ? TRUE : FALSE; } else if (0 == strcmp("verified", key)) { pUser->m_bVerified = json_is_true(value) ? TRUE : FALSE; } else if (0 == strcmp("status", key)) { PERR("%s-->%d\n", key, value->type); POS(); pUser->m_pFeed = weibo_feed_create_json(value); PERR("%d\n", pUser->m_pFeed); PERR("%s\n", ((pweibo_feed)(pUser->m_pFeed))->m_szID->str); } iter = json_object_iter_next(pJson, iter); } json_decref(pJson); return pUser; }
/* Generate a move to definitely settle the position after the game * has been finished. The purpose of this is to robustly determine * life and death status and to distinguish between life in seki and * life with territory. * * The strategy is basically to turn all own living stones into * invincible ones and remove from the board all dead opponent stones. * Stones which cannot be removed, nor turned invincible, are alive in * seki. * * If do_capture_dead_stones is 0, opponent stones are not necessarily * removed from the board. This happens if they become unconditionally * dead anyway. * * Moves are generated in the following order of priority: * 0. Play edge liberties in certain positions. This is not really * necessary, but often it can simplify the tactical and strategical * reading substantially, making subsequent moves faster to generate. * 1. Capture an opponent string in atari and adjacent to own * invincible string. Moves leading to ko or snapback are excluded. * 2. Extend an invincible string to a liberty of an opponent string. * 3. Connect a non-invincible string to an invincible string. * 4. Extend an invincible string towards an opponent string or an own * non-invincible string. * 5. Split a big eyespace of an alive own dragon without invincible * strings into smaller pieces. * 6. Play a liberty of a dead opponent dragon. * * Steps 2--4 are interleaved to try to optimize the efficiency of the * moves. In step 5 too, efforts are made to play efficient moves. By * efficient we here mean moves which are effectively settling the * position and simplify the tactical and strategical reading for * subsequent moves. * * Steps 1--4 are guaranteed to be completely safe. Step 0 and 5 * should also be risk-free. Step 6 on the other hand definitely * isn't. Consider for example this position: * * .XXXXX. * XXOOOXX * XOO.OOX * XOXXXOX * XO.XXOX * ------- * * In order to remove the O stones, it is necessary to play on one of * the inner liberties, but one of them lets O live. Thus we have to * check carefully for blunders at this step. * * Update: Step 0 is only safe against blunders if care is taken not * to get into a shortage of liberties. * Step 5 also has some risks. Consider this position: * * |XXXXX. * |OOOOXX * |..O.OX * |OX*OOX * +------ * * Playing at * allows X to make seki. * * IMPORTANT RESTRICTION: * Before calling this function it is mandatory to call genmove() or * genmove_conservative(). For this function to be meaningful, the * genmove() call should return pass. */ int aftermath_genmove(int *aftermath_move, int color, int under_control[BOARDMAX], int do_capture_dead_stones) { int k; int other = OTHER_COLOR(color); int distance[BOARDMAX]; int score[BOARDMAX]; float owl_hotspot[BOARDMAX]; float reading_hotspot[BOARDMAX]; int dragons[BOARDMAX]; int something_found; int closest_opponent = NO_MOVE; int closest_own = NO_MOVE; int d; int move = NO_MOVE; int pos = NO_MOVE; int best_score; int best_scoring_move; owl_hotspots(owl_hotspot); reading_hotspots(reading_hotspot); /* As a preparation we compute a distance map to the invincible strings. */ for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (!ON_BOARD(pos)) continue; else if (board[pos] == color && worm[pos].invincible) distance[pos] = 0; else if (!do_capture_dead_stones && ((board[pos] == other && worm[pos].unconditional_status == DEAD) || (board[pos] == color && worm[pos].unconditional_status == ALIVE))) distance[pos] = 0; else distance[pos] = -1; } d = 0; do { something_found = 0; for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (ON_BOARD(pos) && distance[pos] == -1) { for (k = 0; k < 4; k++) { int pos2 = pos + delta[k]; if (!ON_BOARD(pos2)) continue; if ((d == 0 || board[pos2] == EMPTY) && distance[pos2] == d) { if (d > 0 && board[pos] == other) { distance[pos] = d + 1; if (closest_opponent == NO_MOVE) closest_opponent = pos; } else if (d > 0 && board[pos] == color) { distance[pos] = d + 1; if (closest_own == NO_MOVE) closest_own = pos; } else if (board[pos] == EMPTY) { distance[pos] = d + 1; something_found = 1; } break; } } } } d++; } while (something_found); if (under_control) { for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (!ON_BOARD(pos)) continue; else if (distance[pos] == -1) under_control[pos] = 0; else under_control[pos] = 1; } } if (debug & DEBUG_AFTERMATH) { int m, n; for (m = 0; m < board_size; m++) { for (n = 0; n < board_size; n++) { pos = POS(m, n); if (distance[pos] > 0) fprintf(stderr, "%2d", distance[pos]); else if (distance[pos] == 0) { if (board[pos] == WHITE) gprintf(" o"); else if (board[pos] == BLACK) gprintf(" x"); else gprintf(" ?"); } else { if (board[pos] == WHITE) gprintf(" O"); else if (board[pos] == BLACK) gprintf(" X"); else gprintf(" ."); } } gprintf("\n"); } gprintf("Closest opponent %1m", closest_opponent); if (closest_opponent != NO_MOVE) gprintf(", distance %d\n", distance[closest_opponent]); else gprintf("\n"); gprintf("Closest own %1m", closest_own); if (closest_own != NO_MOVE) gprintf(", distance %d\n", distance[closest_own]); else gprintf("\n"); } /* Case 0. This is a special measure to avoid a certain kind of * tactical reading inefficiency. * * Here we play on edge liberties in the configuration * * XO. * .*. * --- * * to stop X from "leaking" out along the edge. Sometimes this can * save huge amounts of tactical reading for later moves. */ best_scoring_move = NO_MOVE; best_score = 5; for (pos = BOARDMIN; pos < BOARDMAX; pos++) { int libs; if (board[pos] != EMPTY || distance[pos] == 0) continue; libs = approxlib(pos, color, 3, NULL); if (libs < 3) continue; if (is_self_atari(pos, other)) continue; for (k = 0; k < 4; k++) { int dir = delta[k]; int right = delta[(k+1)%4]; if (!ON_BOARD(pos - dir) && board[pos + dir] == color && board[pos + dir + right] == other && board[pos + dir - right] == other && (libs > countlib(pos + dir) || (libs > 4 && libs == countlib(pos + dir))) && (DRAGON2(pos + dir).safety == INVINCIBLE || DRAGON2(pos + dir).safety == STRONGLY_ALIVE)) { int this_score = 20 * (owl_hotspot[pos] + reading_hotspot[pos]); if (this_score > best_score) { best_score = this_score; best_scoring_move = pos; } } } } if (best_scoring_move != NO_MOVE && safe_move(best_scoring_move, color) == WIN) { *aftermath_move = best_scoring_move; DEBUG(DEBUG_AFTERMATH, "Closing edge at %1m\n", best_scoring_move); return 1; } /* Case 1. */ for (pos = BOARDMIN; pos < BOARDMAX; pos++) { int lib; if (board[pos] == other && worm[pos].unconditional_status != DEAD && countlib(pos) == 1 && ((ON_BOARD(SOUTH(pos)) && distance[SOUTH(pos)] == 0) || (ON_BOARD(WEST(pos)) && distance[WEST(pos)] == 0) || (ON_BOARD(NORTH(pos)) && distance[NORTH(pos)] == 0) || (ON_BOARD(EAST(pos)) && distance[EAST(pos)] == 0))) { findlib(pos, 1, &lib); /* Make sure we don't play into a ko or a (proper) snapback. */ if (countstones(pos) > 1 || !is_self_atari(lib, color)) { *aftermath_move = lib; return 1; } } } /* Cases 2--4. */ if (closest_opponent != NO_MOVE || closest_own != NO_MOVE) { if (closest_own == NO_MOVE) move = closest_opponent; else move = closest_own; /* if we're about to play at distance 1, try to optimize the move. */ if (distance[move] == 2) { char mx[BOARDMAX]; char mark = 0; memset(mx, 0, sizeof(mx)); best_score = 0; best_scoring_move = move; for (pos = BOARDMIN; pos < BOARDMAX; pos++) { int score = 0; int move_ok = 0; if (!ON_BOARD(pos) || distance[pos] != 1) continue; mark++; for (k = 0; k < 4; k++) { int pos2 = pos + delta[k]; if (!ON_BOARD(pos2)) continue; if (distance[pos2] < 1) score--; else if (board[pos2] == EMPTY) score++; else if (mx[pos2] == mark) score--; else { if (board[pos2] == color) { move_ok = 1; score += 7; if (countstones(pos2) > 2) score++; if (countstones(pos2) > 4) score++; if (countlib(pos2) < 4) score++; if (countlib(pos2) < 3) score++; } else { int deltalib = (approxlib(pos, other, MAXLIBS, NULL) - countlib(pos2)); move_ok = 1; score++; if (deltalib >= 0) score++; if (deltalib > 0) score++; } mark_string(pos2, mx, mark); } } if (is_suicide(pos, other)) score -= 3; if (0) gprintf("Score %1m = %d\n", pos, score); if (move_ok && score > best_score) { best_score = score; best_scoring_move = pos; } } move = best_scoring_move; } while (distance[move] > 1) { for (k = 0; k < 4; k++) { int pos2 = move + delta[k]; if (ON_BOARD(pos2) && board[pos2] == EMPTY && distance[pos2] == distance[move] - 1) { move = pos2; break; } } } *aftermath_move = move; return 1; } /* Case 5. * If we reach here, either all strings of a dragon are invincible * or no string is. Next we try to make alive dragons invincible by * splitting big eyes into smaller ones. Our strategy is to search * for an empty vertex with as many eye points as possible adjacent * and with at least one alive but not invincible stone adjacent or * diagonal. */ for (pos = BOARDMIN; pos < BOARDMAX; pos++) { int eyespace_neighbors = 0; int own_neighbors = 0; int own_diagonals = 0; int opponent_dragons = 0; int own_worms = 0; int safety = UNKNOWN; int bonus = 0; int mx[BOARDMAX]; score[pos] = 0; if (board[pos] != EMPTY || distance[pos] != -1) continue; memset(mx, 0, sizeof(mx)); for (k = 0; k < 8; k++) { int pos2 = pos + delta[k]; if (!ON_BOARD(pos2)) continue; if (board[pos2] == EMPTY) { if (k < 4) eyespace_neighbors++; continue; } if (board[pos2] == other) { int origin = dragon[pos2].origin; if (k < 4) { if (dragon[pos2].status == ALIVE) { safety = DEAD; break; } else if (!mx[origin]) { eyespace_neighbors++; opponent_dragons++; } } if (!mx[origin] && dragon[pos2].status == DEAD) { bonus++; if (k < 4 && countlib(pos2) <= 2 && countstones(pos2) >= 3) bonus++; if (k < 4 && countlib(pos2) == 1) bonus += 3; } mx[origin] = 1; } else if (board[pos2] == color) { dragons[pos] = pos2; if (safety == UNKNOWN && dragon[pos2].status == ALIVE) safety = ALIVE; if (DRAGON2(pos2).safety == INVINCIBLE) safety = INVINCIBLE; if (k < 4) { int apos = worm[pos2].origin; if (!mx[apos]) { own_worms++; if (countstones(apos) == 1) bonus += 2; if (countlib(apos) < 6 && approxlib(pos, color, 5, NULL) < countlib(apos)) bonus -= 5; mx[apos] = 1; } if (countlib(apos) <= 2) { int r; int important = 0; int safe_atari = 0; for (r = 0; r < 4; r++) { d = delta[r]; if (!ON_BOARD(apos+d)) continue; if (board[apos+d] == other && dragon[apos+d].status == DEAD) important = 1; else if (board[apos+d] == EMPTY && !is_self_atari(apos+d, other)) safe_atari = 1; } if (approxlib(pos, color, 3, NULL) > 2) { bonus++; if (important) { bonus += 2; if (safe_atari) bonus += 2; } } } own_neighbors++; } else own_diagonals++; } } if (safety == DEAD || safety == UNKNOWN || eyespace_neighbors == 0 || (own_neighbors + own_diagonals) == 0) continue; if (bonus < 0) bonus = 0; score[pos] = 4 * eyespace_neighbors + bonus; if (safety == INVINCIBLE) { score[pos] += own_neighbors; if (own_neighbors < 2) score[pos] += own_diagonals; if (own_worms > 1 && eyespace_neighbors >= 1) score[pos] += 10 + 5 * (own_worms - 2); } else if (eyespace_neighbors > 2) score[pos] += own_diagonals; /* Splitting bonus. */ if (opponent_dragons > 1) score[pos] += 10 * (opponent_dragons - 1); /* Hotspot bonus. */ { int owl_hotspot_bonus = (int) (20.0 * owl_hotspot[pos]); int reading_hotspot_bonus = (int) (20.0 * reading_hotspot[pos]); int hotspot_bonus = owl_hotspot_bonus + reading_hotspot_bonus; /* Don't allow the hotspot bonus to turn a positive score into * a non-positive one. */ if (score[pos] > 0 && score[pos] + hotspot_bonus <= 0) hotspot_bonus = 1 - score[pos]; score[pos] += hotspot_bonus; if (1 && (debug & DEBUG_AFTERMATH)) gprintf("Score %1M = %d (hotspot bonus %d + %d)\n", pos, score[pos], owl_hotspot_bonus, reading_hotspot_bonus); } /* Avoid taking ko. */ if (is_ko(pos, color, NULL)) score[pos] = (score[pos] + 1) / 2; } while (1) { int bb; best_score = 0; move = NO_MOVE; for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (ON_BOARD(pos) && score[pos] > best_score) { best_score = score[pos]; move = pos; } } if (move == NO_MOVE) break; bb = dragons[move]; if (is_illegal_ko_capture(move, color) || !safe_move(move, color) || (DRAGON2(bb).safety != INVINCIBLE && DRAGON2(bb).safety != STRONGLY_ALIVE && owl_does_defend(move, bb, NULL) != WIN) || (!confirm_safety(move, color, NULL, NULL))) { score[move] = 0; } else { /* If we're getting short of liberties, we must be more careful. * Check that no adjacent string or dragon gets more alive by * the move. */ int libs = approxlib(move, color, 5, NULL); int move_ok = 1; if (libs < 5) { for (k = 0; k < 4; k++) { if (board[move + delta[k]] == color && countlib(move + delta[k]) > libs) break; } if (k < 4) { if (trymove(move, color, "aftermath-B", move + delta[k])) { int adjs[MAXCHAIN]; int neighbors; int r; neighbors = chainlinks(move, adjs); for (r = 0; r < neighbors; r++) { if (worm[adjs[r]].attack_codes[0] != 0 && (find_defense(adjs[r], NULL) > worm[adjs[r]].defense_codes[0])) { DEBUG(DEBUG_AFTERMATH, "Blunder: %1m becomes tactically safer after %1m\n", adjs[r], move); move_ok = 0; } } popgo(); for (r = 0; r < neighbors && move_ok; r++) { if (dragon[adjs[r]].status == DEAD && !owl_does_attack(move, adjs[r], NULL)) { DEBUG(DEBUG_AFTERMATH, "Blunder: %1m becomes more alive after %1m\n", adjs[r], move); move_ok = 0; } } } } } if (!move_ok) score[move] = 0; else { *aftermath_move = move; DEBUG(DEBUG_AFTERMATH, "Splitting eyespace at %1m\n", move); return 1; } } } /* Case 6. * Finally we try to play on liberties of remaining DEAD opponent * dragons, carefully checking against mistakes. */ for (pos = BOARDMIN; pos < BOARDMAX; pos++) { int target; int cc = NO_MOVE; int self_atari_ok = 0; if (board[pos] != EMPTY || distance[pos] != -1) continue; target = NO_MOVE; for (k = 0; k < 4; k++) { int pos2 = pos + delta[k]; if (!ON_BOARD(pos2)) continue; if (board[pos2] == other && dragon[pos2].status != ALIVE && (do_capture_dead_stones || worm[pos2].unconditional_status != DEAD) && DRAGON2(pos2).safety != INESSENTIAL) { target = pos2; break; } } if (target == NO_MOVE) continue; /* At this point, (pos) is a move that potentially may capture * a dead opponent string at (target). */ if (!trymove(pos, color, "aftermath-A", target)) continue; /* It is frequently necessary to sacrifice own stones in order * to force the opponent's stones to be removed from the board, * e.g. by adding stones to fill up a nakade shape. However, we * should only play into a self atari if the sacrificed stones * are classified as INESSENTIAL. Thus it would be ok for O to * try a self atari in this position: * * |OOOO * |XXXO * |..XO * |OOXO * +---- * * but not in this one: * * |XXX.. * |OOXX. * |.OOXX * |XXOOX * |.O.OX * +----- */ self_atari_ok = 1; for (k = 0; k < 4; k++) { if (board[pos + delta[k]] == color && DRAGON2(pos + delta[k]).safety != INESSENTIAL) { self_atari_ok = 0; cc = pos + delta[k]; break; } } /* Copy the potential move to (move). */ move = pos; /* If the move is a self atari, but that isn't okay, try to * recursively find a backfilling move which later makes the * potential move possible. */ if (!self_atari_ok) { while (countlib(pos) == 1) { int lib; findlib(pos, 1, &lib); move = lib; if (!trymove(move, color, "aftermath-B", target)) break; } if (countlib(pos) == 1) move = NO_MOVE; } while (stackp > 0) popgo(); if (move == NO_MOVE) continue; /* Make sure that the potential move really isn't a self * atari. In the case of a move found after backfilling this * could happen (because the backfilling moves happened to * capture some stones). */ if (!self_atari_ok && is_self_atari(move, color)) continue; /* Consult the owl code to determine whether the considered move * really is effective. Blunders should be detected here. */ if (owl_does_attack(move, target, NULL) == WIN) { /* If we have an adjacent own dragon, which is not inessential, * verify that it remains safe. */ if (cc != NO_MOVE && !owl_does_defend(move, cc, NULL)) continue; /* If we don't allow self atari, also call confirm safety to * avoid setting up combination attacks. */ if (!self_atari_ok && !confirm_safety(move, color, NULL, NULL)) continue; *aftermath_move = move; DEBUG(DEBUG_AFTERMATH, "Filling opponent liberty at %1m\n", move); return 1; } } /* Case 7. * In very rare cases it turns out we need yet another pass. An * example is this position: * * |..... * |OOOO. * |XXXO. * |.OXO. * |O.XO. * +----- * * Here the X stones are found tactically dead and therefore the * corner O stones have been amalgamated with the surrounding * stones. Since the previous case only allows sacrificing * INESSENTIAL stones, it fails to take X off the board. * * The solution is to look for tactically attackable opponent stones * that still remain on the board but should be removed. */ for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (board[pos] == other && (worm[pos].unconditional_status == UNKNOWN || do_capture_dead_stones) && (DRAGON2(pos).safety == DEAD || DRAGON2(pos).safety == TACTICALLY_DEAD) && worm[pos].attack_codes[0] != 0 && !is_illegal_ko_capture(worm[pos].attack_points[0], color)) { *aftermath_move = worm[pos].attack_points[0]; DEBUG(DEBUG_AFTERMATH, "Tactically attack %1m at %1m\n", pos, *aftermath_move); return 1; } } /* No move found. */ return -1; }
static void showchar(int i, int j, int empty, int xo) { struct dragon_data *d; /* dragon data at (i, j) */ struct dragon_data2 *d2; int x; ASSERT_ON_BOARD2(i, j); x = BOARD(i, j); d = &(dragon[POS(i, j)]); d2 = &(dragon2[d->id]); if (x == EMPTY) { if (xo != 2) fprintf(stderr, " %c", empty); else { int empty_color; char empty_char; if (black_eye[POS(i, j)].color == BLACK) { if (white_eye[POS(i, j)].color == WHITE) empty_color = domain_colors[3]; else empty_color = domain_colors[1]; if (black_eye[POS(i, j)].marginal) empty_char = '!'; else empty_char = 'x'; } else if (white_eye[POS(i, j)].color == WHITE) { empty_color = domain_colors[2]; if (white_eye[POS(i, j)].marginal) empty_char = '!'; else empty_char = 'o'; } else { empty_color = domain_colors[0]; empty_char = '.'; } write_color_char(empty_color, empty_char); } } else { int w; if (xo == 0 || ! ON_BOARD1(d->origin)) { fprintf(stderr, " %c", BOARD(i, j) == BLACK ? 'X' : 'O'); return; } /* Figure out ascii character for this dragon. This is the * dragon number allocated to the origin of this worm. */ w = dragon_num[d->origin]; if (!w) { /* Not yet allocated - allocate next one. */ /* Count upwards for black, downwards for white to reduce confusion. */ if (BOARD(i, j) == BLACK) w = dragon_num[d->origin] = next_black++; else w = dragon_num[d->origin] = next_white--; } w = w%26 + (BOARD(i, j) == BLACK ? 'A' : 'a'); /* Now draw it. */ if (xo == 1) write_color_char(colors[BOARD(i, j)][d->crude_status], w); else if (xo == 2) { if (BOARD(i, j) == BLACK) write_color_char(domain_colors[1], 'X'); else write_color_char(domain_colors[2], 'O'); } else if (xo == 3) write_color_char(colors[BOARD(i, j)][d2->owl_status], w); else if (xo == 4) write_color_char(colors[BOARD(i, j)][d->status], w); } }
void play_solo(Gameinfo *gameinfo, int moves) { SGFTree sgftree; int passes = 0; /* num. consecutive passes */ float move_value; double t1, t2; int save_moves = moves; struct stats_data totalstats; int total_owl_count = 0; /* It tends not to be very imaginative in the opening, * so we scatter a few stones randomly to start with. * We add two random numbers to reduce the probability * of playing stones near the edge. */ int n = 6 + 2*gg_rand()%5; int i, j; komi = 5.5; sgftree_clear(&sgftree); sgftreeCreateHeaderNode(&sgftree, board_size, komi, handicap); sgf_write_header(sgftree.root, 1, get_random_seed(), 5.5, handicap, get_level(), chinese_rules); /* Generate some random moves. */ if (board_size > 6) { do { do { i = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); j = (gg_rand() % 4) + (gg_rand() % (board_size - 4)); } while (!is_allowed_move(POS(i, j), gameinfo->to_move)); gnugo_play_move(POS(i, j), gameinfo->to_move); sgftreeAddPlay(&sgftree, gameinfo->to_move, i, j); sgftreeAddComment(&sgftree, "random move"); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); } while (--n > 0); } t1 = gg_cputime(); memset(&totalstats, '\0', sizeof(totalstats)); while (passes < 2 && --moves >= 0) { int move; reset_owl_node_counter(); move = genmove(gameinfo->to_move, &move_value, NULL); gnugo_play_move(move, gameinfo->to_move); sgffile_add_debuginfo(sgftree.lastnode, move_value); sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); sgffile_output(&sgftree); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); if (move == PASS_MOVE) { passes++; printf("%s(%d): Pass\n", gameinfo->to_move == BLACK ? "Black" : "White", movenum); } else { passes = 0; gprintf("%s(%d): %1m\n", gameinfo->to_move == BLACK ? "Black" : "White", movenum, move); } totalstats.nodes += stats.nodes; totalstats.read_result_entered += stats.read_result_entered; totalstats.read_result_hits += stats.read_result_hits; totalstats.trusted_read_result_hits += stats.trusted_read_result_hits; total_owl_count += get_owl_node_counter(); } t2 = gg_cputime(); /* Two passes and it's over. (EMPTY == BOTH) */ who_wins(EMPTY, stdout); { float score = gnugo_estimate_score(NULL, NULL); sgfWriteResult(sgftree.root, score, 1); } sgffile_output(&sgftree); printf("%10d moves played in %0.3f seconds\n", save_moves-moves, t2-t1); if (save_moves != moves) printf("%10.3f seconds/move\n", (t2-t1)/(save_moves-moves)); printf("%10d nodes\n", totalstats.nodes); printf("%10d read results entered\n", totalstats.read_result_entered); printf("%10d read result hits\n", totalstats.read_result_hits); printf("%10d trusted read result hits\n", totalstats.trusted_read_result_hits); printf("%10d owl nodes\n", total_owl_count); }
bool stone::empty_redistribution() { int except = -1; int target; if (s_influence > 0){ target = BLACK; } else if (s_influence < 0){ target = WHITE; } else { if (stone_block == NULL) return 1; else { stone_block->empty.remove(this); stone_block = NULL; return 1; } } //BFS int visited[BOARD_SIZE*BOARD_SIZE]; memset(visited, 0, sizeof(visited)); queue <int> q; q.push(POS(row, col)); visited[POS(row, col)] = 1; while (!q.empty()) { int top; int mark = 0; top = q.front(); q.pop(); for (int k = 0; k < 4; k++) { if (stone_board->on_board(I(top) + deltai[k], J(top) + deltaj[k])) { int index = POS(I(top) + deltai[k], J(top) + deltaj[k]); if (stone_board->main_board[index]->color == EMPTY) { if (visited[index] == 0) { visited[index] = 1; q.push(index); } } else if (stone_board->main_board[index]->color == OTHER_COLOR(target) && color == EMPTY && mark == 0) { except = index; mark = 1; continue; } else if (stone_board->main_board[index]->color == OTHER_COLOR(target) && color == EMPTY && mark == 1) { continue; } else if (stone_board->main_board[index]->color == target && color == EMPTY) { //IF: check if it is already in for (std::list<stone*>::iterator itor2 = stone_board->main_board[index]->stone_block->empty.begin(); itor2 != stone_board->main_board[index]->stone_block->empty.end(); ++itor2) { if (POS((*itor2)->row, (*itor2)->col) == POS(row, col)){ return 1; } } //ELSE: delete the orignial term, add to the new list if (this->stone_block != NULL) { for (std::list<stone*>::iterator itor = this->stone_block->empty.begin(); itor != this->stone_block->empty.end(); itor++) { if (POS((*itor)->row, (*itor)->col) == POS(row, col)) { this->stone_block->empty.erase(itor); break; } } } stone_board->main_board[index]->stone_block->empty.push_back(this); //mark the stone block this->stone_block = stone_board->main_board[index]->stone_block; return 1; } } } } if (except == -1) { return 0; } //Impossible //except: the influence is negative, but it's surrounded by blacks //It's already in the "except" black block for (std::list<stone*>::iterator itor = stone_board->main_board[except]->stone_block->empty.begin(); itor != stone_board->main_board[except]->stone_block->empty.end(); ++itor) { if (POS((*itor)->row, (*itor)->col) == POS(row, col)){ return 1; } } //ELSE: delete the orignial term, add to the new list this->stone_block->empty.remove(this); stone_board->main_board[except]->stone_block->empty.push_back(this); //mark the stone block this->stone_block = stone_board->main_board[except]->stone_block; return 1; }
static inline void set_hchars(struct part *p, int x, int y, int xl, unsigned c) { xpand_lines(p, y); xpand_line(p, y, x+xl-1); for (; xl; xl--, x++) POS(x, y) = c; }
void XGraphicsOpenGL::DrawPieClip( const XE::VEC2 *pvLines, int numLine, float x, float y, float radius, float angStart, float angEnd, XCOLOR color, int maxSlice ) { if( angStart == angEnd ) return; XE::VEC2 *pvList = _vLists; float angSlice = 360.0f / (float)maxSlice; // float ang = 0; pvList->x = x; pvList->y = y; // 파이의 중심점 pvList++; XE::VEC2 vOut; XE::VEC2 vo; vo.x = x + (sinf(D2R(angStart)) * radius); // 시작각도 버텍스 하나 만들어줌 vo.y = y + (-cosf(D2R(angStart)) * radius); if( ClippingLine( &vOut, pvLines, numLine, x, y, vo.x, vo.y ) ) *pvList = vOut; else *pvList = vo; pvList++; ang += angSlice; const XE::VEC2 *pEnd = &_vLists[ MAX_VERTEX ]; int num = 0; while( ang < angEnd ) { if( ang >= angStart ) // 각도범위에 포함되면 버텍스를 추가 { float rAng = D2R(ang); // 디그리 각도를 라디안각도로 변환 vo.x = x + (sinf(rAng) * radius); vo.y = y + (-cosf(rAng) * radius); if( ClippingLine( &vOut, pvLines, numLine, x, y, vo.x, vo.y ) ) *pvList = vOut; else *pvList = vo; pvList++; num++; // 삼각형 개수 if( XBREAK(pvList > pEnd) ) // 버퍼 오버플로우 되지 않도록 break; } ang += angSlice; } // 마지막각도에 버텍스 하나 더 추가 vo.x = x + (sinf(D2R(angEnd)) * radius); vo.y = y + (-cosf(D2R(angEnd)) * radius); if( ClippingLine( &vOut, pvLines, numLine, x, y, vo.x, vo.y ) ) *pvList = vOut; else *pvList = vo; num++; // gl버텍스버퍼에 옮김 { GLfloat r, g, b, a; r = XCOLOR_RGB_R(color) / 255.0f; g = XCOLOR_RGB_G(color) / 255.0f; b = XCOLOR_RGB_B(color) / 255.0f; a = XCOLOR_RGB_A(color) / 255.0f; GLfloat pos[MAX_VERTEX * 2]={0,}; GLfloat col[MAX_VERTEX * 4]={0,}; // float ratioX = ((float)GetPhyScreenWidth() / GetScreenWidth()) ; // float ratioY = ((float)GetPhyScreenHeight() / GetScreenHeight()); for( int i = 0; i < num+2; i ++ ) // num은 삼각형개수고 +2를 해야 버텍스 개수다 { POS(i, _vLists[i].x, _vLists[i].y); COLOR(i,r,g,b,a); // m_aVertex[i].vPos.x = _vLists[i].x * ratioX; // m_aVertex[i].vPos.y = _vLists[i].y * ratioY; // m_aVertex[i].dwColor = color; } // gl draw glPushMatrix(); glLoadIdentity(); glDisable( GL_TEXTURE_2D ); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // 이건 안해줘도 되네. glVertexPointer(2, GL_FLOAT, 0, pos); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_FLOAT, 0, col); glEnableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_FAN, 0, num+2); // num+2: 버텍스개수 glDisableClientState(GL_COLOR_ARRAY); glEnable( GL_TEXTURE_2D ); glPopMatrix(); } }
//----------------------------------------------------------------------------- // 説明: ルート位置ベクトルの取得 // 引数: // frm [in] フレーム番号 // 返り値: // ルート位置ベクトル // その他: //----------------------------------------------------------------------------- Vector3f CMotionData::GetPosition(size_t frm) const { if (!IsRange(frm)) return Vector3f() = Vector3f::Identity(); return POS(frm); }
int main(int argc, char *argv[]) { int i, n; bool wasRunning = FALSE; bool save_cfg = FALSE; bool change_settings_ui(menu_e *menu, u1_t key, bool *skip_first, cfg_t *cfg); bool show_ip = FALSE; bool config_valid, config_key = FALSE; bool config_ip = FALSE, config_nm = FALSE, config_gw = FALSE, config_am = FALSE; u4_t key; menu_e menu; int addr_mode; int ip[4], nm[4], gw[4], bc[4]; FILE *cfp, *efp; char *config_file = ROOT_DIR "/.5370.config"; cfg_t *cfg = &cfg_buf; dsp_7seg_init(FALSE); // panic routine can't use display until bus is setup // silently ignores unrecognized arguments for (i=1; i<argc; i++) { if (strcmp(argv[i], "-bg") == 0) background_mode = TRUE; if (strcmp(argv[i], "-ip") == 0) show_ip = TRUE; if (strcmp(argv[i], "-no") == 0) menu_action = FALSE; if (strcmp(argv[i], "?")==0 || strcmp(argv[i], "-?")==0 || strcmp(argv[i], "--?")==0 || strcmp(argv[i], "-h")==0 || strcmp(argv[i], "h")==0 || strcmp(argv[i], "-help")==0 || strcmp(argv[i], "--h")==0 || strcmp(argv[i], "--help")==0) { printf( "-rcl|-recall [name] load key settings from named profile\n" "-hpib-hard use the original HPIB hardware interface, assuming installed\n" "-hpib-sim simulate the HPIB interface in software (debug mode)\n" "-hpib-net simulate and re-direct transfers over an Ethernet connection\n" "-ip show IP address of Ethernet interface and exit\n" ); xit(0); } } lprintf("HP%s v%d.%d\n", INST_STR, FIRMWARE_VER_MAJ, FIRMWARE_VER_MIN); lprintf("compiled: %s %s\n", __DATE__, __TIME__); sim_args(TRUE, argc, argv); hpib_args(TRUE, argc, argv); sim_init(); web_server_init(); if (!menu_action) printf("menu action disabled\n"); reset: // To support the action of the 'reset' key most code files have a reset routine that zeros static variables. // This is similar to the C runtime idea of zeroing the bss when a program is first run. if (wasRunning) { wasRunning = FALSE; net_reset(NET_HPIB); net_reset(NET_TELNET); web_server_stop(); skip_first = save_cfg = config_key = config_ip = config_nm = config_gw = config_am = FALSE; } sim_reset(); if (!(bus_read(RREG_LDACSR) & DSR_VOK)) { lprintf("waiting for 5370 power\n"); usleep(1000000); while (!(bus_read(RREG_LDACSR) & DSR_VOK)) { sched_yield(); usleep(250000); } lprintf("5370 power on\n"); usleep(1000000); } else { lprintf("5370 is powered on\n"); } // display firmware version dsp_7seg_init(TRUE); dsp_7seg_str(DSP_LEFT, INST_STR, DSP_CLEAR); dsp_7seg_chr(POS(10), 'v'); dsp_7seg_num(POS(11), POS_IS_LSD, FIRMWARE_VER_MAJ, DEFAULT_WIDTH, SPACE_FILL); dsp_7seg_num(POS(12), POS_IS_MSD, FIRMWARE_VER_MIN, FIELD_WIDTH(0), ZERO_FILL); dsp_7seg_dp(POS(12)); dsp_leds_clr_all(); delay(2000); if ((cfp = fopen(config_file, "r")) == NULL) { if (errno != ENOENT) sys_panic(config_file); config_valid = FALSE; } else { while (fgets(lbuf, LBUF, cfp)) { if ((sscanf(lbuf, "key 0x%x", &key) == 1) && (key == 0xcafe5370)) config_key = TRUE; else if (sscanf(lbuf, "am %d", &addr_mode) == 1) config_am = TRUE; else if (sscanf(lbuf, "ip %d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) config_ip = TRUE; else if (sscanf(lbuf, "nm %d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]) == 4) config_nm = TRUE; else if (sscanf(lbuf, "gw %d.%d.%d.%d", &gw[0], &gw[1], &gw[2], &gw[3]) == 4) config_gw = TRUE; else ; } assert((addr_mode == 0) || (addr_mode == 1)); menu = cfg->menu = (addr_mode == 0)? M_DHCP : M_IP; if (config_key && config_ip && config_nm && config_gw && config_am) { printf("valid config file %s\n", config_file); config_valid = TRUE; if (menu == M_IP) { printf("setting interface address\n"); sprintf(lbuf, "ifconfig eth0 %d.%d.%d.%d netmask %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3], nm[0], nm[1], nm[2], nm[3]); if (menu_action) system(lbuf); sprintf(lbuf, "route add default %d.%d.%d.%d", gw[0], gw[1], gw[2], gw[3]); if (menu_action) system(lbuf); } } else { printf("invalid config file %s\n", config_file); config_valid = FALSE; } fclose(cfp); } if (!config_valid) { menu = cfg->menu = M_DHCP; // try DHCP first if not valid config } #define ENET_RETRY 20 if (menu == M_DHCP) { // see if interface configured by DHCP gw[3]=gw[2]=gw[1]=gw[0]=0; // ifconfig doesn't tell us the gateway, only the broadcast which we don't care about // sometimes the link is slow to come up, so retry a few times for (i=0; i<ENET_RETRY; i++) { if ((efp = popen("ifconfig eth0", "r")) == NULL) sys_panic("ifconfig eth0"); char *lp = lbuf; n=0; while (fgets(lp, LBUF, efp)) { if ((n = sscanf(lp, "%*[ ]inet addr:%d.%d.%d.%d Bcast:%d.%d.%d.%d Mask:%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3], &bc[0], &bc[1], &bc[2], &bc[3], &nm[0], &nm[1], &nm[2], &nm[3])) == 12) break; } pclose(efp); if (n == 12) break; delay(1000); } } else { i=0; // interface configured manually above } if (i != ENET_RETRY) { for (i=0; i<4; i++) { cfg->ip[i] = ip[i]; cfg->nm[i] = nm[i]; cfg->gw[i] = gw[i]; } if (menu == M_DHCP) lprintf("via DHCP "); lprintf("eth0: ip %d.%d.%d.%d mask %d.%d.%d.%d ", ip[0], ip[1], ip[2], ip[3], nm[0], nm[1], nm[2], nm[3]); if (menu != M_DHCP) lprintf("gw %d.%d.%d.%d", gw[0], gw[1], gw[2], gw[3]); lprintf("\n"); dsp_7seg_str(DSP_LEFT, "ip", DSP_CLEAR); display_ipaddr(cfg->ip); } else { lprintf("eth0: not configured from DHCP?"); dsp_7seg_str(DSP_LEFT, "no dhcp?", DSP_CLEAR); } if (!config_valid && (i == ENET_RETRY)) { // configuration not valid, DHCP failed, so set some defaults menu = cfg->menu = M_IP; bcopy(default_ipinfo, cfg->if_ipinfo, sizeof(default_ipinfo)); save_cfg = TRUE; } if (show_ip) xit(0); delay(2000); // show ip on display for a moment before continuing net_connect(NET_HPIB, SERVER, NULL, HPIB_TCP_PORT); net_connect(NET_TELNET, SERVER, NULL, TELNET_TCP_PORT); web_server_start(); // place a call here to setup your measurement extension code meas_extend_example_init(); // reset key held down during a reboot -- drop into menu mode preempt_reset_key(TRUE); // while in the boot routine the reset key either starts the app or saves the changed config app_state = S_MENU; while (1) { u1_t key; sim_input(); // for remote debugging of menu mode key = handler_dev_display_read(RREG_KEY_SCAN); // called instead of bus_read() so simulated keys will be returned switch(app_state) { case S_MENU: if (key != KEY(RESET)) { app_state = S_START; break; } dsp_7seg_str(DSP_LEFT, "ready", DSP_CLEAR); printf("ready\n"); dsp_led_set(RESET); wait_key_release(); dsp_led_clr(RESET); dsp_7seg_str(DSP_LEFT, "chg settings", DSP_CLEAR); printf("menu mode\n"); skip_first = TRUE; menu = M_HALT; // first menu item displayed // light up the keys valid during menu mode for (i=0; settings_keys[i].key; i++) { dsp_led_set(settings_keys[i].key); } app_state = S_MENU_POLL; break; case S_MENU_POLL: if (key == KEY(RESET)) { dsp_led_set(RESET); wait_key_release(); dsp_led_clr(RESET); app_state = S_MENU_DONE; break; } if (change_settings_ui(&menu, key, &skip_first, cfg)) save_cfg = TRUE; break; case S_MENU_DONE: if (!skip_first && (menu == M_HALT)) { // Debian takes a while to halt, but nicely clears the GPIOs so the // display goes blank right when halted. // Angstrom with Gnome disabled halts very fast, but doesn't // clear the GPIOs like Debian. So we get the PRU to poll the LEDs // until they go off, then blank the display. dsp_7seg_str(DSP_LEFT, " halting...", DSP_CLEAR); printf("halting...\n"); #ifdef DIST_DEBIAN if (menu_action) system("halt"); exit(0); #endif #ifdef DIST_ANGSTROM dsp_7seg_chr(POS(0), ' '); // preload address & data send_pru_cmd(PRU_HALT); if (menu_action) system("halt"); exit(0); #endif } else if (menu == M_CANCEL || (skip_first && (menu == M_HALT))) { app_state = S_START; break; } else { if (menu != M_DHCP) menu = M_IP; if (menu != cfg->menu) save_cfg = TRUE; } if (save_cfg) { dsp_7seg_str(DSP_LEFT, "config changed", DSP_CLEAR); delay(2000); cfg->menu = menu; if (menu == M_DHCP) { dsp_7seg_str(DSP_LEFT, "using dhcp mode", DSP_CLEAR); } else { dsp_7seg_str(DSP_LEFT, "using ip mode", DSP_CLEAR); } delay(2000); dsp_7seg_str(DSP_LEFT, "saving config", DSP_CLEAR); if ((cfp = fopen(config_file, "w")) == NULL) sys_panic(config_file); printf("writing config file %s\n", config_file); fprintf(cfp, "key 0xcafe5370\n"); fprintf(cfp, "am %d\n", (cfg->menu == M_DHCP)? 0:1); fprintf(cfp, "ip %d.%d.%d.%d\n", cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]); fprintf(cfp, "nm %d.%d.%d.%d\n", cfg->nm[0], cfg->nm[1], cfg->nm[2], cfg->nm[3]); fprintf(cfp, "gw %d.%d.%d.%d\n", cfg->gw[0], cfg->gw[1], cfg->gw[2], cfg->gw[3]); fclose(cfp); delay(2000); } app_state = S_START; break; case S_START: if (wasRunning) { // if previous sim was interrupted must reset before starting new one goto reset; } preempt_reset_key(FALSE); sim_main(); preempt_reset_key(TRUE); handler_dev_display_read(RREG_KEY_SCAN); // flush extra sim reset key, if any delay(1000); // this sim was interrupted, so can't restart a new sim without doing a reset first wasRunning = TRUE; // if key still down after one second delay enter menu mode, else treat as simple reset if (handler_dev_display_read(RREG_KEY_SCAN) == KEY(RESET)) { app_state = S_MENU; } else { goto reset; } break; } } return 0; }
INDIConfig::INDIConfig(wxWindow *parent, int devtype) : wxDialog(parent, wxID_ANY, _("INDI Configuration"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { auto sizerLabelFlags = wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL; auto sizerButtonFlags = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL; auto sizerSectionFlags = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL; auto sizerTextFlags = wxALIGN_LEFT | wxALL | wxEXPAND; int border = 2; dev_type = devtype; gui = NULL; int pos; wxGridBagSizer *gbs = new wxGridBagSizer(0, 20); wxBoxSizer *sizer; pos = 0; gbs->Add(new wxStaticText(this, wxID_ANY, _("INDI Server")), POS(pos, 0), SPAN(1, 1), sizerSectionFlags, border); pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("Hostname")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); host = new wxTextCtrl(this, wxID_ANY); gbs->Add(host, POS(pos, 1), SPAN(1, 1), sizerTextFlags, border); pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("Port")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); port = new wxTextCtrl(this, wxID_ANY); gbs->Add(port, POS(pos, 1), SPAN(1, 1), sizerTextFlags, border); pos ++; connect_status = new wxStaticText(this, wxID_ANY, _("Disconnected")); gbs->Add(connect_status,POS(pos, 0), SPAN(1, 1), wxALIGN_RIGHT | wxALL | wxALIGN_CENTER_VERTICAL, border); gbs->Add(new wxButton(this, MCONNECT, _("Connect")), POS(pos, 1), SPAN(1, 1), sizerButtonFlags, border); pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _T("========")), POS(pos, 0), SPAN(1, 1), wxALIGN_LEFT | wxALL, border); devlabel = new wxStaticText(this, wxID_ANY, _("Device")); if (devtype == TYPE_CAMERA) { devlabel->SetLabel(_("Camera")); } else if (devtype == TYPE_MOUNT) { devlabel->SetLabel(_("Mount")); } gbs->Add(devlabel,POS(pos, 1), SPAN(1, 1), wxALIGN_LEFT | wxALL, border); pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("Driver")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); dev = new wxComboBox(this, wxID_ANY, _T("")); gbs->Add(dev, POS(pos, 1), SPAN(1, 1), sizerTextFlags, border); if (devtype == TYPE_CAMERA) { pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("CCD")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); ccd = new wxComboBox(this, wxID_ANY, _T("")); ccd->Append(_("Main imager")); ccd->Append(_("Guider")); gbs->Add(ccd, POS(pos, 1), SPAN(1, 1), sizerTextFlags, border); } pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("Port")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); devport = new wxTextCtrl(this, wxID_ANY); gbs->Add(devport, POS(pos, 1), SPAN(1, 1), sizerTextFlags, border); pos ++; gbs->Add(new wxStaticText(this, wxID_ANY, _("Other options")), POS(pos, 0), SPAN(1, 1), sizerLabelFlags, border); gbs->Add(new wxButton(this, MINDIGUI, _("INDI")), POS(pos, 1), SPAN(1, 1), sizerButtonFlags, border); sizer = new wxBoxSizer(wxVERTICAL) ; sizer->Add(gbs); sizer->AddSpacer(10); sizer->Add(CreateButtonSizer(wxOK | wxCANCEL)); sizer->AddSpacer(10); SetSizer(sizer); sizer->SetSizeHints(this) ; sizer->Fit(this) ; }
// recursive function to try a game int trygame(int depth, int doUpdate) { struct Node *parent = (struct Node*)0; uint64_t goban_hash = goban.hash; int myturn = goban.turn; int result; int pos; int win; int x,y; int haspoints; uint64_t hash; if (depth == MAXDEPTH) return goban_getOwner(target); // see if we can use nt3 hash = hash_get(0, target, goban.hash, NODETYPE_POS |USE_TARGET); parent = hash_get_node(hash); pos = get_best_move( parent, (NODETYPE_POS| USE_TARGET| NODETYPE_MOVE), NULL ); if (parent->visits >= MIN_SPECIAL_VISITS && parent->visits % UPDATE_SPECIAL_RATE == 0) { update_special_node(pos); } if (mode == 1) { int p; for(y = state.boardsize; y >= 1; y--) for(x = 1; x <= state.boardsize; x++) update_special_node(POS(x,y)); p = engine_getbestmove(); if (p) pos = p; } goban_move(pos); #if LOG_MOVES_RATE > 0 if (depth == 0 && tries % LOG_MOVES_RATE == 0) { out(fileGTP, "Target %p ", target); } if (depth < 10 && tries % LOG_MOVES_RATE == 0) out(fileGTP, "%d%p ", 0, pos); #endif result = trygame(depth+1, parent->visits > 0); #if LOG_MOVES_RATE > 0 if (depth == 0 && tries % LOG_MOVES_RATE == 0) out(fileGTP, " res=%d, %r\n", result, goban.score); #endif haspoints = 0; for(y = state.boardsize; y >= 1; y--) for(x = 1; x <= state.boardsize; x++) { int targ = POS(x,y); if (targ != target) continue; result = goban_getOwner(targ); if (!result) continue; haspoints = 1; } if (!haspoints) { //out(fileInfo, "Failure getOwner(target)=%d\n", goban_getOwner(POS(7,5))); //outboard(fileInfo); } if (haspoints && doUpdate) for(y = state.boardsize; y >= 1; y--) for(x=1; x <= state.boardsize; x++) { int targ = POS(x,y); if (targ != target) continue; result = goban_getOwner(targ); if (!result) continue; win = (result == myturn ? 1 : 0); // store nt 3 hash_set_node(hash_get(pos, targ, goban_hash, NODETYPE_POS|NODETYPE_TARGET|NODETYPE_MOVE), win); hash_set_node(hash_get(pos, targ, goban_hash, NODETYPE_POS|NODETYPE_TARGET), win); } // update target-agnostic nodes (generic uct) if (haspoints && doUpdate && goban.score) { win = (myturn * goban.score > 0 ? 1 : 0); hash_set_node(hash_get(pos, 0, goban_hash, NODETYPE_POS|NODETYPE_MOVE), win); hash_set_node(hash_get(pos, 0, goban_hash, NODETYPE_POS), win); } if (haspoints && depth == 0) { for(y = state.boardsize; y >= 1; y--) for(x=1; x <= state.boardsize; x++) { int targ = POS(x,y); result = goban_getOwner(targ); pos_stat[targ].total++; if (result == myturn) pos_stat[targ].won++; else if (result == -myturn) pos_stat[targ].lost++; } //outboard(fileGTP); //update_special_node(pos); return 1; } return 0; return result; }
/* * Compute how much (area) of the given pixel is inside the triangle. * Vertices MUST be specified in counter-clockwise order. * Return: coverage in [0, 1]. */ static GLfloat compute_coveragef(const GLfloat v0[3], const GLfloat v1[3], const GLfloat v2[3], GLint winx, GLint winy) { /* Given a position [0,3]x[0,3] return the sub-pixel sample position. * Contributed by Ray Tice. * * Jitter sample positions - * - average should be .5 in x & y for each column * - each of the 16 rows and columns should be used once * - the rectangle formed by the first four points * should contain the other points * - the distrubition should be fairly even in any given direction * * The pattern drawn below isn't optimal, but it's better than a regular * grid. In the drawing, the center of each subpixel is surrounded by * four dots. The "x" marks the jittered position relative to the * subpixel center. */ #define POS(a, b) (0.5+a*4+b)/16 static const GLfloat samples[16][2] = { /* start with the four corners */ { POS(0, 2), POS(0, 0) }, { POS(3, 3), POS(0, 2) }, { POS(0, 0), POS(3, 1) }, { POS(3, 1), POS(3, 3) }, /* continue with interior samples */ { POS(1, 1), POS(0, 1) }, { POS(2, 0), POS(0, 3) }, { POS(0, 3), POS(1, 3) }, { POS(1, 2), POS(1, 0) }, { POS(2, 3), POS(1, 2) }, { POS(3, 2), POS(1, 1) }, { POS(0, 1), POS(2, 2) }, { POS(1, 0), POS(2, 1) }, { POS(2, 1), POS(2, 3) }, { POS(3, 0), POS(2, 0) }, { POS(1, 3), POS(3, 0) }, { POS(2, 2), POS(3, 2) } }; const GLfloat x = (GLfloat) winx; const GLfloat y = (GLfloat) winy; const GLfloat dx0 = v1[0] - v0[0]; const GLfloat dy0 = v1[1] - v0[1]; const GLfloat dx1 = v2[0] - v1[0]; const GLfloat dy1 = v2[1] - v1[1]; const GLfloat dx2 = v0[0] - v2[0]; const GLfloat dy2 = v0[1] - v2[1]; GLint stop = 4, i; GLfloat insideCount = 16.0F; ASSERT(dx0 * dy1 - dx1 * dy0 >= 0.0); /* area >= 0.0 */ for (i = 0; i < stop; i++) { const GLfloat sx = x + samples[i][0]; const GLfloat sy = y + samples[i][1]; /* cross product determines if sample is inside or outside each edge */ GLfloat cross = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0])); /* Check if the sample is exactly on an edge. If so, let cross be a * positive or negative value depending on the direction of the edge. */ if (cross == 0.0F) cross = dx0 + dy0; if (cross < 0.0F) { /* sample point is outside first edge */ insideCount -= 1.0F; stop = 16; } else { /* sample point is inside first edge */ cross = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0])); if (cross == 0.0F) cross = dx1 + dy1; if (cross < 0.0F) { /* sample point is outside second edge */ insideCount -= 1.0F; stop = 16; } else { /* sample point is inside first and second edges */ cross = (dx2 * (sy - v2[1]) - dy2 * (sx - v2[0])); if (cross == 0.0F) cross = dx2 + dy2; if (cross < 0.0F) { /* sample point is outside third edge */ insideCount -= 1.0F; stop = 16; } } } } if (stop == 4) return 1.0F; else return insideCount * (1.0F / 16.0F); }
//----------------------------------------------------------------------------------------------- void CRenderCamera::SetPos ( const tVect3& vPos) { POS(m_TM) = vPos; RebuildMatrices(); }
PyObject * smds_Correlator_output(PyObject *self) { smds_Correlator *p = (smds_Correlator *)self; PyObject *r = NULL, *o = NULL; PyArrayObject *Gs = NULL, *ts = NULL; double norm, *G, *t, bin = 0.0; int num; int i, k, l = 0; // set l = 1 if g(0) is included if (ACFType) r = PyInstance_New(ACFType, NULL, NULL); else PyErr_SetString(PyExc_SystemError, "Unable to create ACF object."); if (!r) return NULL; num = 8*(K+1); // 129 if g(0) is included for (k=1; k < (K+1); k++) num -= p->fill[k]; if (num <= 0) { Py_DECREF(r); Py_RETURN_NONE; } Gs = (PyArrayObject*)PyArray_FromDims(1, &num, PyArray_DOUBLE); if (!Gs) goto bail; ts = (PyArrayObject*)PyArray_FromDims(1, &num, PyArray_DOUBLE); if (!ts) goto bail; if (PyObject_SetAttrString(r, "G", (PyObject*)Gs) == -1 || PyObject_SetAttrString(r, "t", (PyObject*)ts) == -1) goto bail; t = (double*)(ts->data); G = (double*)(Gs->data); /* t[0] = 0.0; if (!p->sum) G[0] = 0.0; else G[0] = p->G0 / (p->sum*p->sum) * (double)(p->dur); */ for (k=1; k < (K+1); k++) { norm = (double)(p->dur/(1<<(k-1))) / p->M_dir[k]; for (i=(k==1?-8:0); i < 8-p->fill[k]; i++) { bin = t[l] = bin + (double)(1 << (k-1)) * p->bw * 1e-3; G[l] = norm * p->G[POS(k,i)] / p->M_del[POS(k,i)]; if (finite(G[l])) l++; } } if (l != num) Gs->dimensions[0] = ts->dimensions[0] = l; Py_DECREF(Gs); Py_DECREF(ts); return r; bail: if (o) { Py_DECREF(o); } if (r) { Py_DECREF(r); } if (Gs) { Py_DECREF(Gs); } if (ts) { Py_DECREF(ts); } return NULL; }
void ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) { ASSIGNC ((NEG (a) && POS (b)) || (NEG (a) && POS (result)) || (POS (b) && POS (result))); }
// argument is of type smds.Task.RTR PyObject * smds_Correlator_data (PyObject *self, PyObject *o) { smds_Correlator *c = (smds_Correlator*)self; // PyObject *o = NULL; PyArrayObject *a = NULL; short *data = NULL; int k, i, n, rr, num; /* *** This func is called only from append() when the arg is a RTR. if (!PyArg_ParseTuple(args, "O!", RTRType, &o)) return NULL; // o is borrowed if (!PyInstance_Check(o)) { PyErr_SetString(PyExc_TypeError, "Argument must be of type smds.RTR."); return NULL; } */ if (!(o = PyObject_GetAttrString(o, "data"))) return NULL; // o is ours a = (PyArrayObject*)PyArray_ContiguousFromObject(o, PyArray_SHORT, 1, 1); Py_DECREF(o); o = NULL; if (!a) return NULL; data = (short*)a->data; num = a->dimensions[0]; if (num <= 0) { Py_DECREF(a); Py_RETURN_NONE; } for (n=0; n < num; n++) { c->dur++; c->zero[1] = (double)data[n]; c->sum += c->zero[1]; c->G0 += c->zero[1] * c->zero[1]; for (k=1; k < (K+1); k++) { // New datum has entered zero, trickle up if (k != K) c->zero[k+1] += c->zero[k]; if (!c->fill[k-1] && c->fill[k]) c->start[POS(k, 8-(c->fill[k]--))] = c->zero[k]; // Do multiplications c->M_dir[k] += c->zero[k]; i = (k==1?0:k*8); rr = c->pos[k]; do { c->M_del[i] += c->shift[POS(k,rr)]; c->G[i] += c->zero[k] * c->shift[POS(k,rr)]; i++; if (++rr == 8) rr = (k==1?-8:0); } while (rr != c->pos[k]); // Shift rr = c->pos[k]-1; // oldest position becomes newest if (rr < (k==1?-8:0)) rr = 7; if (k != K) // Shift oldest position to next group's acc c->acc[k+1] += c->shift[POS(k,rr)]; // Shift this group's acc into newest pos c->shift[POS(k,rr)] = (k==1?c->zero[k]:c->acc[k]); c->pos[k] = rr; // save newest pos c->parity ^= 1 << k; // Recurse c->acc[k] = c->zero[k] = 0.0; if (c->parity & (1 << k)) break; } // each k } // each datum Py_DECREF(a); Py_RETURN_NONE; } // smds_Correlator_data()
static int get_final_status(int i, int j) { return final_status[POS(i, j)]; }
// argument is of type smds_Correlator or smds.Task.RTR PyObject * smds_Correlator_append(PyObject *self, PyObject *args) { smds_Correlator *a = (smds_Correlator*)self, *b = NULL; PyObject *o = NULL, *c = NULL; double swap[(K+1)], *t1 = swap, *t2 = swap+8; int k, i, rr, phi, rem = 0, used = 0; // k, sigma, tau, phi, rho, xsi if (!PyArg_ParseTuple(args, "O", &o)) return NULL; // o is borrowed if (PyInstance_Check(o)) { c = PyObject_GetAttrString(o, "__class__"); if (!c) return NULL; i = PyObject_Compare(c, RTRType); Py_DECREF(c); if (PyErr_Occurred()) return NULL; if (i == 0) return smds_Correlator_data(self, o); } if (!PyObject_TypeCheck(o, &smds_CorrelatorType)) { PyErr_SetString(PyExc_TypeError, "Argument must be of type smds.Task.RTR or smds.Analysis.Correlator!"); return NULL; } b = (smds_Correlator*)o; if (a->bw != b->bw) { PyErr_SetString(PyExc_ValueError, "Binwidth mis-match in smds_Correlator_append()."); return NULL; } // Reorder a->shift so that pos[k] == 0 for all k for (k=1; k < (K+1); k++) { if (a->pos[k] == (k==1?-8:0)) continue; rr = a->pos[k]; i = 0; do { swap[i++] = a->shift[POS(k,rr)]; if (++rr == 8) rr = (k==1?-8:0); } while (rr != a->pos[k]); if (k==1) { for (i=0; i < 16; i++) a->shift[i] = swap[i]; a->pos[k] = -8; } else { for (i=0; i < 8; i++) a->shift[POS(k,i)] = swap[i]; a->pos[k] = 0; } } // Compute overlap correlation contributions for each lag, Steps 1-3 { phi = (b->fill[1] < 8 ? 8 : 16-(b->fill[1])); // first 8 of k==1 (requires no summation afterward) for (rr = 0; rr < 8; rr++) for (i=0; i <= (rr < phi ? rr : phi-1); i++) { a->M_del[rr] += a->shift[rr-i]; a->G[rr] += b->start[i] * a->shift[rr-i]; } } for (k=1; k < (K+1); k++) { if (k==1) phi = (b->fill[1] < 8 ? 8-(b->fill[1]) : 0); else phi = 8-(b->fill[k]); for (rr = 0; rr < 8; rr++) // Lag for (i=0; i <= (rr < phi ? rr+8 : phi+rem-1); i++) // Overlap position { a->M_del[POS(k,rr)] += a->shift[POS(k,rr)-i]; a->G[POS(k,rr)] += b->start[POS(k-1,i)] * a->shift[POS(k,rr)-i]; } if (a->fill[k] && !b->fill[k-1]) for (rr=used; a->fill[k] && rr < phi+8; a->fill[k]--, rr++) { a->start[POS(k,8-(a->fill[k]))] = b->start[POS(k-1,rr)]; used++; } // Sum shift/start for the next k rem = (rem+phi)/2; if (b->fill[k]) { // Save a->shift for later use for (i=0; i < 8; i++) t2[i] = a->shift[POS(k,i)]; } if (k != K) for (rr = POS(k,7), i=0; i < 8; i++,rr--) { a->shift[rr] = a->shift[rr-i] + a->shift[rr-i-1]; b->start[rr] = b->start[rr-i] + b->start[rr-i-1]; } if (b->fill[k-1]) { // Restore a->shift from last iteration for (i=0; i < 8; i++) a->shift[POS(k-1,i)] = t1[i]; } if (b->fill[k]) for (i=0; i < 8; i++) t1[i] = t2[i]; used >>= 1; } // Step 4 for (i=0; i < 8*(K+1); i++) { a->G[i] += b->G[i]; a->M_del[i] += b->M_del[i]; } for (i=0; i < (K+1); i++) { a->M_dir[i] += b->M_dir[i]; } a->G0 += b->G0; a->sum += b->sum; a->dur += b->dur; a->parity = b->parity; // Step 5, copy B's shift register to A for (k=1; k < (K+1) && !(b->fill[k]); k++) { if (k == 1) for (i=0, rr=0; i < 8; i++, rr += 2) t1[i] = a->shift[rr] + a->shift[rr+1]; else { for (i=0, rr=0; i < 4; i++, rr += 2) t1[i] = t1[rr] + t1[rr+1]; for (i=4, rr=0; i < 8; i++, rr += 2) t1[i] = a->shift[POS(k,rr)] + a->shift[POS(k,rr+1)]; } a->pos[k] = b->pos[k]; a->acc[k] = b->acc[k]; for (rr=(k==1?-8:0); rr < 8; rr++) a->shift[POS(k,rr)] = b->shift[POS(k,rr)]; } if (k == 1) // k is the first group of b->start that isn't full { // Step 6 phi = 16-(b->fill[k]); rr = 16-phi; if (phi % 2) { a->acc[k+1] = a->shift[rr]; a->parity |= (1 << k); rr++; } else { a->acc[k+1] = 0; a->parity &= !(1 << k); } for (i=0; rr < 16; rr += 2, i++) t1[i] = a->shift[rr] + a->shift[rr+1]; a->pos[k] = 16-phi; for (i=(a->pos[k]), rr=(b->pos[k]); i < 16; i++) { a->shift[i] = b->shift[POS(k,rr)]; if (++rr == 8) rr = -8; } rem = phi/2; } else if (k < (K+1)) { // Step 7 phi = 8-(b->fill[k]); for (rr=0, i=0; rr < 8; rr += 2, i++) t2[i] = a->shift[POS(k,rr)] + a->shift[POS(k,rr+1)]; for (i=0, rr=(b->pos[k]); i < phi; i++) { a->shift[POS(k,i)] = b->shift[POS(k,rr)]; if (++rr == 8) rr = 0; } for (rr=0; i < 8; i++, rr++) a->shift[POS(k,i)] = t1[rr]; a->acc[k] = b->acc[k]; if (phi % 2) { if (k != K) a->acc[k+1] = t1[rr]; a->parity |= (1 << k); rr++; } else { if (k != K) a->acc[k+1] = 0; a->parity &= !(1 << k); } for(i=0; rr < 8; rr += 2, i++) t1[i] = t1[rr] + t1[rr+1]; for(rr=0; rr < 4; rr++, i++) t1[i] = t2[rr]; rem = phi/2+4; } // Step 8 for (k++; k < (K+1); k++) { if (!rem) { if (k != K) a->acc[k+1] = 0; a->parity &= !(1 << k); continue; } a->pos[k] = 8-rem; for (i=0, rr=(a->pos[k]); rr < 8; i++, rr++) { t2[i] = a->shift[POS(k,rr)]; a->shift[POS(k,rr)] = t1[i]; } if (rem % 2) { if (k != K) a->acc[k+1] = t2[0]; a->parity |= (1 << k); rr = 1; } else { if (k != K) a->acc[k+1] = 0; a->parity &= !(1 << k); rr = 0; } for (i=0; rr < rem; rr+=2, i++) t1[i] = t2[rr] + t2[rr+1]; rem >>= 1; } // Step 10, fill the zero-delay register for (k=2, i=1, rr=-8; k < (K+1); k++) { // k is the current zero we're filling // i/rr is the current position in the shift register (xsi) // bin width of level k is 2**(k-1) // if parity[k], fill up zero with half a bin width, i.e. 2**(k-2) // when rr == 8, add in acc[i+1] if parity[i] a->zero[k] = 0.0; if (a->parity & (1 << (k-1))) { for (rem = 1 << (k-2); rem > 0; rem -= (1 << (i-1))) { if (rr == 8) { if (a->parity & (1 << i)) { a->zero[k] += a->acc[i+1]; rem -= 1 << (i-1); if (rem < 0) break; // Error } i++; rr = 0; if (rem == 0) break; // Normal termination } a->zero[k] += a->shift[POS(i,rr++)]; } if (rem < 0) { PyErr_SetString(PyExc_Exception, "smds_Correlator_append(): Error calculating zero[]!"); return NULL; // g_error("smds_Correlator_append(): Error calculating zero[%d], i=%d, " // "rr=%d, rho=%d, par = %d", k, i, rr, rem, a->parity); } } } // Done. Py_RETURN_NONE; }
/* Generate move in empty corner or in middle of small board.*/ void fuseki(int color) { int i = -1; int j = -1; int width; /* Side of the open region required in the corner. */ int empty_corner_value = EMPTY_CORNER_VALUE * board_size/19; /* Return immediately if --disable_fuseki option used. */ if (disable_fuseki) return; set_symmetries(); /* Search in fuseki database unless disabled by --nofusekidb option. */ if (fusekidb && search_fuseki_database(color)) return; /* On 9x9, only play open corners after the first move if nothing * else useful is found. */ if (board_size == 9 && stones_on_board(color) > 0) empty_corner_value = 5; if (board_size <= 11) { /* For boards of size 11x11 or smaller we first go for the center point. */ int middle = board_size/2; if (openregion(middle-2, middle+2, middle-2, middle+2)) { announce_move(POS(middle, middle), 45, color); } } if (board_size < 9) return; if (board_size >= 18) width = 8; else if (board_size == 9) width = 5; else width = board_size/2; if (openregion(0, width-1, board_size-width, board_size-1)) { choose_corner_move(UPPER_RIGHT, &i, &j); announce_move(POS(i, j), empty_corner_value, color); } if (openregion(board_size-width, board_size-1, 0, width-1)) { choose_corner_move(LOWER_LEFT, &i, &j); announce_move(POS(i, j), empty_corner_value, color); } if (openregion(board_size-width, board_size-1, board_size-width, board_size-1)) { choose_corner_move(LOWER_RIGHT, &i, &j); announce_move(POS(i, j), empty_corner_value, color); } if (openregion(0, width-1, 0, width-1)) { choose_corner_move(UPPER_LEFT, &i, &j); announce_move(POS(i, j), empty_corner_value, color); } }
static void draw_planet(ModeInfo * mi, planetstruct * planet) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); gravstruct *gp = &gravs[MI_SCREEN(mi)]; double D; /* A distance variable to work with */ register unsigned char cmpt; D = POS(X) * POS(X) + POS(Y) * POS(Y) + POS(Z) * POS(Z); if (D < COLLIDE) D = COLLIDE; D = sqrt(D); D = D * D * D; for (cmpt = X; cmpt < DIMENSIONS; cmpt++) { ACC(cmpt) = POS(cmpt) * GRAV / D; if (decay) { if (ACC(cmpt) > MaxA) ACC(cmpt) = MaxA; else if (ACC(cmpt) < -MaxA) ACC(cmpt) = -MaxA; VEL(cmpt) = VEL(cmpt) + ACC(cmpt); VEL(cmpt) *= DAMP; } else { /* update velocity */ VEL(cmpt) = VEL(cmpt) + ACC(cmpt); } /* update position */ POS(cmpt) = POS(cmpt) + VEL(cmpt); } gp->x = planet->xi; gp->y = planet->yi; if (POS(Z) > -ALMOST) { planet->xi = (int) ((double) gp->width * (HALF + POS(X) / (POS(Z) + DIST))); planet->yi = (int) ((double) gp->height * (HALF + POS(Y) / (POS(Z) + DIST))); } else planet->xi = planet->yi = -1; /* Mask */ XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); Planet(gp->x, gp->y); if (trail) { XSetForeground(display, gc, planet->colors); XDrawPoint(display, MI_WINDOW(mi), gc, gp->x, gp->y); } /* Move */ gp->x = planet->xi; gp->y = planet->yi; planet->ri = RADIUS; /* Redraw */ XSetForeground(display, gc, planet->colors); Planet(gp->x, gp->y); }