void *thread(void *arg) { int i, j; char* outboard = ((t_args_t *)arg)->outboard; char* inboard = ((t_args_t *)arg)->inboard; const int nrows = ((t_args_t *)arg)->nrows; const int ncols = ((t_args_t *)arg)->ncols; const int rStart = ((t_args_t *)arg)->rStart; const int rEnd = ((t_args_t *)arg)->rEnd; const int cStart = ((t_args_t *)arg)->cStart; const int cEnd = ((t_args_t *)arg)->cEnd; const int LDA = nrows; for (i = rStart; i < rEnd; i++) { for (j = cStart; j < cEnd; j++) { const int inorth = mod (i-1, nrows); const int isouth = mod (i+1, nrows); const int jwest = mod (j-1, ncols); const int jeast = mod (j+1, ncols); const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, inorth, jeast) + BOARD (inboard, i, jwest) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jwest) + BOARD (inboard, isouth, j) + BOARD (inboard, isouth, jeast); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); } } pthread_exit(NULL); }
/*----------------------------------------------------------------------------*/ void make_levl (YT_BOOL to_files, int ii, int jj, int lev) { GO_POSI *l[MAX_ALL_POSI]; int n, in, d; char fname[80]; GO_BOARD *a; int i, j; //--------------------------- //char post[80]; //sprintf (post, "-l%d", lev); //make_stderr_ (FALSE, 0,0,0,0); // в дальнейшем сделать этло через скрипты Tcl.. //make_stderr_ (to_files, "B/", ii, jj, post); //sprintf (fname, "B/%dx%dall.pos", ii, jj); //fprintf (stderr, "\nExtract %d-nd level from File: %s \n", lev, fname); //--------------------------- // читаем файл позиций в массив n = read_file_posi (fname, l, MAX_ALL_POSI, ii, jj); // просматриваем массив вычисляя рейтинг сложности для каждой позиции for (in = 0; in < n; in++) { d = calc_difficult (l[in]); if (d == lev) { // подходящий уровень сложности // сначала надо убрать рабочую информацию (цифры) из позиции // сделаем копию и очистим доску от оценок--плюсиков (p_calc) //p_copy = xo_pos_copy (/* NULL */p_copy, l[i]); //a = p_copy->a; a = (l[in])->a; for (i = 0; i < a->isize; i++) for (j = 0; j < a->jsize; j++) { if (BOARD (a, i, j) == STONE_NONE) continue; if (BOARD (a, i, j) == STONE_WHITE) continue; if (BOARD (a, i, j) == STONE_BLACK) continue; BOARD (a, i, j) = STONE_NONE; } posi_show (l[in]); //num_lev++; // считаем выход для этого уровня //if (num_lev == MAX_LEV_POSI) break; } } printf ("\n"); //--------------------------- //make_stderr_ (FALSE, 0,0,0,0); //--------------------------- return; }
/*---------------------------------------------------------------------------*/ void myhash_test () { Hashposition pos; unsigned long hash; int result; Hashtable *movehash; int i, j; //------------ GO_BOARD *b; //------------ int isize = 2; int jsize = 3; //int boardsize = 3; //int size_node = sizeof (Hashnode); //------------ printf ("\n"); //UNUSED (b3x3); movehash = gohash_create (isize, jsize, 10 /* 0 *//*MEMORY*/); for (i = 0; i < isize; i++) for (j = 0; j < jsize; j++) { b = aboard_begin (isize, jsize); BOARD (b, i, j) = STONE_BLACK; hash = myhash_calc (movehash, b, &pos); if (!myhash_get_result (movehash, hash, &pos, &result, NULL)) { result = (i+1)*10 + (j+1); myhash_set_result (movehash, hash, &pos, result, i+j) ; } } hashtable_dump (movehash, /* STDERR, */ /* TRUE */ FALSE); for (i = 0; i < isize; i++) for (j = 0; j < jsize; j++) { b = aboard_begin (isize, jsize); BOARD (b, i, j) = STONE_BLACK; hash = myhash_calc (movehash, b, &pos); if (myhash_get_result (movehash, hash, &pos, &result, NULL)) printf ("result = %d \n\n", result); else printf ("result not found \n\n"); } return; }
char* sequential_game_of_life (char* outboard, char* inboard, const int nrows, const int ncols, const int gens_max) { /* HINT: in the parallel decomposition, LDA may not be equal to nrows! */ const int LDA = nrows; int curgen, i, j; printf("%d\n", 2); for (curgen = 0; curgen < gens_max; curgen++) { /* HINT: you'll be parallelizing these loop(s) by doing a geometric decomposition of the output */ for (j = 0; j < ncols; j++) { for (i = 0; i < nrows; i++) { const int inorth = mod (i-1, nrows); const int isouth = mod (i+1, nrows); const int jwest = mod (j-1, ncols); const int jeast = mod (j+1, ncols); // printf("jwest-%d, jeast-%d, inorth-%d, isouth-%d\n", jwest,jeast,inorth,isouth); const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, inorth, jeast) + BOARD (inboard, i, jwest) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jwest) + BOARD (inboard, isouth, j) + BOARD (inboard, isouth, jeast); // printf("%d\n",neighbor_count); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); } } SWAP_BOARDS( outboard, inboard ); } printf("%d\n", 3); /* * We return the output board, so that we know which one contains * the final result (because we've been swapping boards around). * Just be careful when you free() the two boards, so that you don't * free the same one twice!!! */ return inboard; }
extern void ShowMove(hintdata * phd, const int f) { char *sz; TanBoard anBoard; if (f) { move *pm; GList *plSelList = MoveListGetSelectionList(phd); if (!plSelList) return; /* the button is toggled */ pm = MoveListGetMove(phd, plSelList); MoveListFreeSelectionList(plSelList); memcpy(anBoard, msBoard(), sizeof(TanBoard)); ApplyMove(anBoard, pm->anMove, FALSE); UpdateMove((BOARD(pwBoard))->board_data, anBoard); } else { sz = g_strdup("show board"); UserCommand(sz); g_free(sz); } #if USE_BOARD3D RestrictiveRedraw(); #endif }
static int openregion(struct board_lib_state_struct *internal_state, int i1, int i2, int j1, int j2) { int x, y; if (i1 > i2) return openregion(internal_state, i2, i1, j1, j2); if (j1 > j2) return openregion(internal_state, i1, i2, j2, j1); /* Disregard parts of the region off the board. This is convenient * in order not to have to special-case tiny boards. It also secures * against potential reading outside the board[] array boundaries. */ if (i1 < 0) i1 = 0; if (j1 < 0) j1 = 0; if (i2 >= internal_state->board_size) i2 = internal_state->board_size - 1; if (j2 >= internal_state->board_size) j2 = internal_state->board_size - 1; for (x = i1; x <= i2; x++) for (y = j1; y <= j2; y++) if (BOARD(x, y) != EMPTY) return 0; return 1; }
/*----------------------------------------------------------------------------*/ int calc_difficult (GO_POSI *pos) { int d, lmin=+100, s=0; int i, j; GO_BOARD *board = pos->a; int isize = board->isize; int jsize = board->jsize; // основная область доски с камнями for (i=0; i < isize; i++) for (j=0; j < jsize; j++) { s = BOARD (board, i,j); if (s == STONE_WHITE) continue; else if (s == STONE_BLACK) continue; else if (s == STONE_NONE) continue; s = s-48; //OUTD (s); lmin = MIN (lmin, s); } if (lmin == +100) d = 0; else d = lmin; //OUTD (d); return (d); }
static void DialogClose(GtkDialog * UNUSED(dialog), gint response, void *UNUSED(data)) { if ((GtkResponseType) response == GTK_RESPONSE_OK) { /* Apply new settings */ char *texStr; /* Copy new settings to preview material */ curDetails->mat = col3d; *curDetails->pBoardMat = col3d; if (useTexture) { texStr = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(textureComboBox)); if (!strcmp(texStr, NO_TEXTURE_STRING)) col3d.textureInfo = 0; else { BoardData *bd = (BOARD(pwPrevBoard))->board_data; ClearTextures(bd->bd3d); GetTextures(bd->bd3d, bd->rd); } } UpdatePreview(); gtk_widget_queue_draw(curDetails->preview); } /* Hide dialog so can be reshown quickly */ gtk_widget_hide(pwColourDialog3d); }
/* * This is used in the original code version. It changed the modulus function call * To if/else statements. Which were later removed in other versions */ static inline void update(int i, int j, char* outboard, char* inboard, const int nrows, const int ncols){ const int LDA = nrows; int inorth; int isouth; int jwest; int jeast; if(i == 0) inorth = nrows - 1; else inorth = i-1; if(i == nrows - 1) isouth = 0; else isouth = i+1; if(j == 0) jwest = ncols - 1; else jwest = j-1; if(j == ncols - 1) jeast = 0; else jeast = j+1; const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, inorth, jeast) + BOARD (inboard, i, jwest) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jwest) + BOARD (inboard, isouth, j) + BOARD (inboard, isouth, jeast); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); }
void* parallel_run(void* args) { int n = (intptr_t) args; int rows_from = n * slice; int rows_to = rows_from + slice; int i, j, ii, jj, inorth, isouth, jwest, jeast; for (i = rows_from; i < rows_to; i ++) { for (j = 0; j < ncols; j ++) { //for (ii = i; ii < i + BLOCK_SIZE; ii++) { inorth = (i-1) & mask; isouth = (i+1) & mask; // for (jj = j; jj < j + BLOCK_SIZE; jj++) { jwest = (j-1) & mask; jeast = (j+1) & mask; const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, i, jwest) + BOARD (inboard, isouth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jeast) + BOARD (inboard, inorth, jeast) + BOARD (inboard, isouth, j); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); // } // } } } }
/*----------------------------------------------------------------------------*/ int find_moves_random (GO_BOARD *t, int numfind, long *p_moves, int num) { int n, i, j; for (n=0; n < numfind; n++) { if (!board_random_stone (t, &i, &j) ) break; // нет даже случайных, т.е. - никаких! BOARD (t, i, j) = STONE_BLACK; (p_moves[num++]) = (long) xo_malloc_move (i, j); } return (num); }
static int openregion(int i1, int i2, int j1, int j2) { int x, y; if (i1 > i2) return openregion(i2, i1, j1, j2); if (j1 > j2) return openregion(i1, i2, j2, j1); for (x = i1; x <= i2; x++) for (y = j1; y <= j2; y++) if (BOARD(x, y) != EMPTY) return 0; return 1; }
/*----------------------------------------------------------------------------*/ int find_moves_all (GO_BOARD *t, long *p_moves, int num) { int i, j; for (i=0; i < t->isize; i++) for (j=0; j < t->jsize; j++) { if (BOARD (t, i, j) != STONE_NONE) continue; (p_moves[num++]) = (long) xo_malloc_move (i, j); // потом надо это все освобождать !!!!! // т.е. вызывать функцию "aigo_freemoves" } return (num); }
void initialize_neighbour_counts (char * board, const int nrows, const int ncols){ int i,j; for (i = 0; i < nrows; i++) { for (j = 0; j< ncols; j++) { if (IS_ALIVE(BOARD(board, i, j))) { const int inorth = mod (i-1, nrows); const int isouth = mod (i+1, nrows); const int jwest = mod (j-1, ncols); const int jeast = mod (j+1, ncols); INCR_AT (board, inorth, jwest); INCR_AT (board, inorth, j); INCR_AT (board, inorth, jeast); INCR_AT (board, i, jwest); INCR_AT (board, i, jeast); INCR_AT (board, isouth, jwest); INCR_AT (board, isouth, j); INCR_AT (board, isouth, jeast); } } } // printf("-----\n"); /* for (i = 0; i < nrows; i++) { for (j = 0; j< ncols; j++) { printf("%02x\n",board[i+nrows*j]); } } */ }
/*----------------------------------------------------------------------------*/ int find_moves_cont (GO_WORK *w, GO_BOARD *t, long *p_moves, int num) { GO_MOVES cdames; int n, i, j; // находим все контактные дамэ work_get_contact_dames (w, &cdames); for (n=0; n < cdames.moves_num; n++) { i = (cdames.moves)[n].i; j = (cdames.moves)[n].j; BOARD (t, i, j) = STONE_BLACK; (p_moves[num++]) = (long) xo_malloc_move (i, j); } return (num); }
void GetStyleFromRCFile(GtkStyle** ppStyle, char* name, GtkStyle* psBase) { /* Note gtk 1.3 doesn't seem to have a nice way to do this... */ BoardData *bd = BOARD(pwBoard)->board_data; GtkStyle *psDefault, *psNew; GtkWidget *dummy, *temp; char styleName[100]; /* Get default style so only changes to this are applied */ temp = gtk_button_new(); gtk_widget_ensure_style(temp); psDefault = gtk_widget_get_style( temp ); /* Get Style from rc file */ strcpy(styleName, "gnubg-"); strcat(styleName, name); dummy = gtk_label_new(""); gtk_widget_ensure_style(dummy); gtk_widget_set_name(dummy, styleName); /* Pack in box to make sure style is loaded */ gtk_box_pack_start(GTK_BOX(bd->table), dummy, FALSE, FALSE, 0); psNew = gtk_widget_get_style(dummy); /* Base new style on base style passed in */ *ppStyle = gtk_style_copy(psBase); /* Make changes to fg+bg and copy to selected states */ if (memcmp(&psNew->fg[GTK_STATE_ACTIVE], &psDefault->fg[GTK_STATE_ACTIVE], sizeof(GdkColor))) memcpy(&(*ppStyle)->fg[GTK_STATE_NORMAL], &psNew->fg[GTK_STATE_ACTIVE], sizeof(GdkColor)); if (memcmp(&psNew->fg[GTK_STATE_NORMAL], &psDefault->fg[GTK_STATE_NORMAL], sizeof(GdkColor))) memcpy(&(*ppStyle)->fg[GTK_STATE_NORMAL], &psNew->fg[GTK_STATE_NORMAL], sizeof(GdkColor)); memcpy(&(*ppStyle)->fg[GTK_STATE_SELECTED], &(*ppStyle)->fg[GTK_STATE_NORMAL], sizeof(GdkColor)); if (memcmp(&psNew->base[GTK_STATE_NORMAL], &psDefault->base[GTK_STATE_NORMAL], sizeof(GdkColor))) memcpy(&(*ppStyle)->base[GTK_STATE_NORMAL], &psNew->base[GTK_STATE_NORMAL], sizeof(GdkColor)); memcpy(&(*ppStyle)->bg[GTK_STATE_SELECTED], &(*ppStyle)->base[GTK_STATE_NORMAL], sizeof(GdkColor)); /* Update the font if different */ if (!gtk_compare_fonts(psNew, psDefault)) gtk_set_font(*ppStyle, psNew); /* Remove useless widgets */ gtk_widget_destroy(dummy); g_object_ref_sink(G_OBJECT(temp)); g_object_unref(G_OBJECT(temp)); }
/*----------------------------------------------------------------------------*/ int find_moves_defs (GO_WORK *w, GO_STONE stone, GO_BOARD *t, long *p_moves, int num) { GO_MOVES *mvs = moves_create (); moves_init (mvs); int my_num = find_try_defends (w, stone, mvs); int n, i, j; for (n=0; n < my_num; n++) { i = ((mvs->moves)[n]).i; j = ((mvs->moves)[n]).j; BOARD (t, i, j) = STONE_BLACK; (p_moves[num++]) = (long) xo_malloc_move (i, j); } return (num); }
/* Helper for the reading_hotspots() function below. */ static void mark_string_hotspot_values(float values[BOARDMAX], int m, int n, float contribution) { int i, j, k; /* If p[m][n] is EMPTY, we just give the contribution to close empty * vertices. This is a rough simplification. */ if (BOARD(m, n) == EMPTY) { for (i = -1; i <= 1; i++) for (j = -1; j <= 1; j++) if (BOARD(m+i, n+j) == EMPTY) values[POS(m+i, n+j)] += contribution; return; } /* Otherwise we give contribution to liberties and diagonal * neighbors of the string at (m, n). */ for (i = 0; i < board_size; i++) for (j = 0; j < board_size; j++) { if (BOARD(i, j) != EMPTY) continue; for (k = 0; k < 8; k++) { int di = deltai[k]; int dj = deltaj[k]; if (IS_STONE(BOARD(i+di, j+dj)) && same_string(POS(i+di, j+dj), POS(m, n))) { if (k < 4) { values[POS(i, j)] += contribution; break; } else { if (BOARD(i+di, j) == EMPTY || countlib(POS(i+di, j)) <= 2 || BOARD(i, j+dj) == EMPTY || countlib(POS(i, j+dj)) <= 2) values[POS(i, j)] += contribution; break; } } } } }
char* game_of_life (char* outboard, char* inboard, const int nrows, const int ncols, const int gens_max) { /* HINT: in the parallel decomposition, LDA may not be equal to nrows! */ const int LDA = nrows; int curgen; for (curgen = 0; curgen < gens_max; curgen++) { /* HINT: you'll be parallelizing these loop(s) by doing a geometric decomposition of the output */ /** * Pragma directive invoking Open MP parallelization for the two nester for loops * Ensured that i and j declarations happen within the scope of the open MP * parallelization so that each thread have their own dedicated i and j variables * **/ #pragma omp parallel num_threads(NUM_THREADS) { int i, j; //Need these inside omp pragme so that they are not shared between threads int thread_num = omp_get_thread_num(); //Gets the current threads num identifier //Split the outer for loop equally between all threads in NUM_THREADS for (i = thread_num*nrows/NUM_THREADS ; i < (thread_num+1)*nrows/NUM_THREADS; i++) { const int inorth = mod (i-1, nrows); //LCIM - mod only uses 'i' value const int isouth = mod (i+1, nrows); //Declare all eight neighbours and current cell. //Compute, north, north-east, current, east, south, and south-west char nw; char n = BOARD (inboard, inorth, mod (-1, ncols)); char ne = BOARD (inboard, inorth, 0); char w; char c = BOARD (inboard, i, mod (-1, ncols)); char e = BOARD (inboard, i, 0); char sw; char s = BOARD (inboard, isouth, mod (-1, ncols)); char se = BOARD (inboard, isouth, 0); for (j = 0; j < ncols; j++) { const int jwest = mod (j-1, ncols); const int jeast = mod (j+1, ncols); //Shift the neighbour values to the left //This enables us to save computation in each stride of j //Only need to compute three new values each stride: // north-east // east // south-east nw = n; n = ne; ne = BOARD (inboard, inorth, jeast); w = c; c = e; e = BOARD (inboard, i, jeast); sw = s; s = se; se = BOARD (inboard, isouth, jeast); const char neighbor_count = nw + n + ne + w + e + sw + s + se; BOARD(outboard, i, j) = alivep (neighbor_count, c); } } } SWAP_BOARDS( outboard, inboard ); } /* * We return the output board, so that we know which one contains * the final result (because we've been swapping boards around). * Just be careful when you free() the two boards, so that you don't * free the same one twice!!! */ return inboard; }
/** * Parallelized implementation of the game of life */ void* loop_parellize(void* arg){ structArgs *a; a = (structArgs*) arg; int nrows = a->nrows; char* outboard = a->outboard; char* inboard = a->inboard; int threadNum = a->threadNum; int ncols = a->ncols; int gens_max = a->gens_max; int initial_i = threadNum*(nrows/NUM_THREADS); int maximum_i = initial_i + (nrows/NUM_THREADS); int i,j; const int LDA = nrows; int vari = nrows/NUM_THREADS; int varj = ncols/2; int j2,i2,curgen; int jself, jnw, jn, jne, jw, je, jsw, js, jse; int iself, inw, in, ine, iw, ie, isw, is, ise; for (curgen = 0; curgen < gens_max; curgen++) { // Optimization: loop switching j and i loops for (j = 0; j < ncols; j+=varj) { for (i = initial_i; i < maximum_i; i+=vari) { // Optimization: Code Motion, Improved formula for inorth and isouth const int inorth = (i==0) ? nrows-1 : i-1; const int isouth = (i==nrows-1) ? 0 : i+1; // Optimization: Tiling for(j2=j;j2<j+varj;j2++){ // Optimization: Improved formula for jwest and jeast const int jwest = (j2 == 0)? ncols-1: j2-1; const int jeast = (j2 == ncols-1)? 0 : j2+1; if(j2 == j){ // Optimization: Loop iteration memory sharing inw = jnw = BOARD (inboard, inorth, jwest); in = jn = BOARD (inboard, inorth, j2); ine = jne = BOARD (inboard, inorth, jeast); iw = jw = BOARD (inboard, i, jwest); iself = jself = BOARD (inboard, i, j2); ie = je = BOARD (inboard, i, jeast); isw = jsw = BOARD (inboard, isouth, jwest); is = js = BOARD (inboard, isouth, j2); ise = jse = BOARD (inboard, isouth, jeast); } else{ //Optimization: Loop iteration memory sharing inw = jnw = jn; in = jn = jne; ine = jne = BOARD (inboard, inorth, jeast); iw = jw = jself; iself = jself = je; ie = je = BOARD (inboard, i, jeast); isw = jsw = js; is = js = jse; ise = jse = BOARD (inboard, isouth, jeast); } for(i2=i; i2<i+vari;i2++){ // printf("jwest-%d, jeast-%d, inorth-%d, isouth-%d, ThreadNum-%d\n", jwest,jeast,inorth,isouth,threadNum); if(i2>i){ //Optimization: Loop iteration memory sharing const int isouth2 = (i2==nrows-1) ? 0 : i2+1; inw = iw; in = iself; ine = ie; iw = isw; iself = is; ie = ise; isw = BOARD (inboard, isouth2, jwest); is = BOARD (inboard, isouth2, j2); ise = BOARD (inboard, isouth2, jeast); } const char neighbor_count = inw + in + ine + iw + ie + isw + is + ise; // printf("%d\n", neighbor_count); BOARD(outboard, i2, j2) = alivep (neighbor_count, iself); } } } } // Optimizaton: pthread barrier pthread_barrier_wait(a->barrp); SWAP_BOARDS( outboard, inboard ); } pthread_exit(0); }
static void ascii_showboard(void) { int i, j; char letterbar[64]; int last_pos_was_move; int pos_is_move; int dead; int last_move = get_last_move(); make_letterbar(board_size, letterbar); set_handicap_spots(board_size); printf("\n"); printf(" White (O) has captured %d stone%s\n", black_captured, black_captured == 1 ? "" : "s"); printf(" Black (X) has captured %d stone%s\n", white_captured, white_captured == 1 ? "" : "s"); if (showscore) { if (current_score_estimate == NO_SCORE) printf(" No score estimate is available yet.\n"); else if (current_score_estimate < 0) printf(" Estimated score: Black is ahead by %d\n", -current_score_estimate); else if (current_score_estimate > 0) printf(" Estimated score: White is ahead by %d\n", current_score_estimate); else printf(" Estimated score: Even!\n"); } printf("\n"); fflush(stdout); printf("%s", letterbar); if (get_last_player() != EMPTY) { gfprintf(stdout, " Last move: %s %1m", get_last_player() == WHITE ? "White" : "Black", last_move); } printf("\n"); fflush(stdout); for (i = 0; i < board_size; i++) { printf(" %2d", board_size - i); last_pos_was_move = 0; for (j = 0; j < board_size; j++) { if (POS(i, j) == last_move) pos_is_move = 128; else pos_is_move = 0; dead = (dragon_status(POS(i, j)) == DEAD) && showdead; switch (BOARD(i, j) + pos_is_move + last_pos_was_move) { case EMPTY+128: case EMPTY: printf(" %c", hspots[i][j]); last_pos_was_move = 0; break; case BLACK: printf(" %c", dead ? 'x' : 'X'); last_pos_was_move = 0; break; case WHITE: printf(" %c", dead ? 'o' : 'O'); last_pos_was_move = 0; break; case BLACK+128: printf("(%c)", 'X'); last_pos_was_move = 256; break; case WHITE+128: printf("(%c)", 'O'); last_pos_was_move = 256; break; case EMPTY+256: printf("%c", hspots[i][j]); last_pos_was_move = 0; break; case BLACK+256: printf("%c", dead ? 'x' : 'X'); last_pos_was_move = 0; break; case WHITE+256: printf("%c", dead ? 'o' : 'O'); last_pos_was_move = 0; break; default: fprintf(stderr, "Illegal board value %d\n", (int) BOARD(i, j)); exit(EXIT_FAILURE); break; } } if (last_pos_was_move == 0) { if (board_size > 10) printf(" %2d", board_size - i); else printf(" %1d", board_size - i); } else { if (board_size > 10) printf("%2d", board_size - i); else printf("%1d", board_size - i); } printf("\n"); } fflush(stdout); printf("%s\n\n", letterbar); fflush(stdout); if (clock_on) { clock_print(WHITE); clock_print(BLACK); } } /* end ascii_showboard */
char* sequential_game_of_life_parallel (char* outboard, char* inboard, const int nrows, const int ncols, const int gens_max, const int sector, int *status, pthread_mutex_t *mutex, pthread_cond_t *cv) { /* HINT: in the parallel decomposition, LDA may not be equal to nrows! */ int curgen, i, j; int row_start, col_start; int row_end, col_end; //Splitting what quadrant we work on. if(sector == 0 || sector == 2){ row_start = 1; row_end = nrows/2; } else{ row_start = nrows/2; row_end = nrows - 1; } if(sector == 0 || sector == 1){ col_start = 1; col_end = ncols/2; } else{ col_start = ncols/2; col_end = ncols - 1; } const int LDA = nrows; char mem_access[3]; char cent; for (curgen = 0; curgen < gens_max; curgen++) { char neighbor_count; //The overlapping sections if (sector == 0){ //j == 0 //i == 0 COUNT_AND_BOARD(inboard, outboard, neighbor_count, 0, 0, nrows - 1, 1, ncols - 1, 1); //j == 0 //i == 1 -> i == nrows/2 - 1 I_CODE_WITH_J(0, ncols - 1, 1); //j == 1 -> j == ncols/2 - 1 //i == 0 //J_CODE_WITH_I(0, nrows - 1, 1); for (j = col_start; j < col_end; j++) { COUNT_AND_BOARD(inboard, outboard, neighbor_count, 0, j, nrows - 1, 1, j - 1, j + 1); } } else if(sector == 1){ //j == 0 //i == nrows - 1 COUNT_AND_BOARD(inboard, outboard, neighbor_count, nrows - 1, 0, nrows - 2, 0, ncols - 1, 1); //j == 0 //i == nrows/2 -> i == nrows - 2 I_CODE_WITH_J(0, ncols - 1, 1); //j == 1 -> j == ncols/2 - 1 //i == nrows - 1 //J_CODE_WITH_I(nrows - 1, nrows - 2, 0); for (j = col_start; j < col_end; j++) { COUNT_AND_BOARD(inboard, outboard, neighbor_count, nrows - 1, j, nrows - 2, 0, j - 1, j + 1); } } else if(sector == 2){ //j == ncols - 1 //i == 0 COUNT_AND_BOARD(inboard, outboard, neighbor_count, 0, ncols - 1, nrows - 1, 1, ncols - 2, 0); //j == ncols - 1 //i == 1 -> i == nrows/2 - 1 I_CODE_WITH_J(ncols - 1, ncols - 2, 0); //j == ncols/2 -> j == ncols - 2 //i == 0 //J_CODE_WITH_I(0, nrows - 1, 1); for (j = col_start; j < col_end; j++) { COUNT_AND_BOARD(inboard, outboard, neighbor_count, 0, j, nrows - 1, 1, j - 1, j + 1); } } else{ //j == ncols - 1 //i == nrows - 1 COUNT_AND_BOARD(inboard, outboard, neighbor_count, nrows - 1, ncols - 1, nrows - 2, 0, ncols - 2, 0); //j == ncols - 1 //i == nrows/2 -> i == nrows - 2 I_CODE_WITH_J(ncols - 1, ncols - 2, 0); //j == ncols/2 -> j == ncols - 2 //i == nrows - 1 //J_CODE_WITH_I(nrows - 1, nrows - 2, 0); for (j = col_start; j < col_end; j++) { COUNT_AND_BOARD(inboard, outboard, neighbor_count, nrows - 1, j, nrows - 2, 0, j - 1, j + 1); } } //Main code part, no if/else branching //Unroleld once in the i dimension, as well as a block on j of size 4. int jj; for (jj = col_start; jj < col_end; jj+= J_BLOCK_SIZE) { for (j = jj; j < min(jj + J_BLOCK_SIZE, col_end); j++) { //Initializing sum mem_access[0] = 0; mem_access[1] = BOARD (inboard, row_start-1, j-1) + BOARD (inboard, row_start-1, j) + BOARD (inboard, row_start-1, j+1); mem_access[2] = BOARD (inboard, row_start, j-1) + BOARD (inboard, row_start, j) + BOARD (inboard, row_start, j+1); cent = 0; neighbor_count = mem_access[1] + mem_access[2]; for(i = row_start; i < row_end - 1; i+=2) { //1 neighbor_count += cent; cent = BOARD (inboard, i, j); neighbor_count = neighbor_count - mem_access[0] - cent; mem_access[0] = mem_access[1]; mem_access[1] = mem_access[2]; mem_access[2] = BOARD (inboard, i+1, j-1) + BOARD (inboard, i+1, j) + BOARD (inboard, i+1, j+1); neighbor_count += mem_access[2]; BOARD(outboard, i, j) = alivep (neighbor_count, cent); //2 neighbor_count += cent; cent = BOARD (inboard, i+1, j); neighbor_count = neighbor_count - mem_access[0] - cent; mem_access[0] = mem_access[1]; mem_access[1] = mem_access[2]; mem_access[2] = BOARD (inboard, i+2, j-1) + BOARD (inboard, i+2, j) + BOARD (inboard, i+2, j+1); neighbor_count += mem_access[2]; BOARD(outboard, i+1, j) = alivep (neighbor_count, cent); //COUNT_AND_BOARD_IJ(inboard, outboard, neighbor_count, i, j); } neighbor_count += cent; cent = BOARD (inboard, i, j); neighbor_count = neighbor_count - mem_access[0] - cent; mem_access[0] = mem_access[1]; mem_access[1] = mem_access[2]; mem_access[2] = BOARD (inboard, i+1, j-1) + BOARD (inboard, i+1, j) + BOARD (inboard, i+1, j+1); neighbor_count += mem_access[2]; BOARD(outboard, i, j) = alivep (neighbor_count, cent); } } //SWAP_BOARDS( outboard, inboard ); //I don't like that weird do while wrapper. char *temp = outboard; outboard = inboard; inboard = temp; pthread_mutex_lock(mutex); *status = *status | (1 << sector); if(*status == 0b1111){ *status = 0; pthread_cond_broadcast(cv); } else{ pthread_cond_wait(cv, mutex); } //Everyone finished working on their sector, can start the next sector pthread_mutex_unlock(mutex); } /* * We return the output board, so that we know which one contains * the final result (because we've been swapping boards around). * Just be careful when you free() the two boards, so that you don't * free the same one twice!!! */ return inboard; }
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); } }
char* sequential_game_of_life (char* outboard_, char* inboard_, const int nrows_, const int ncols_, const int gens_max) { /* HINT: in the parallel decomposition, LDA may not be equal to nrows! */ nrows = nrows_; ncols = ncols_; outboard = outboard_; inboard = inboard_; LDA = nrows; slice = (nrows / NUM_THREADS); mask = nrows - 1; pthread_t *thread = (pthread_t*)malloc(NUM_THREADS * sizeof(pthread_t)); if (nrows_ <= 32 && ncols_ <= 32) { int curgen, i, j; for (curgen = 0; curgen < gens_max; curgen++) { for (i = 0; i < nrows; i++) { for (j = 0; j < ncols; j++) { const int inorth = mod (i-1, nrows); const int isouth = mod (i+1, nrows); const int jwest = mod (j-1, ncols); const int jeast = mod (j+1, ncols); const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, i, jwest) + BOARD (inboard, isouth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jeast) + BOARD (inboard, inorth, jeast) + BOARD (inboard, isouth, j); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); } } SWAP_BOARDS( outboard, inboard ); } } else { int curgen, i; for (curgen = 0; curgen < gens_max; curgen++) { for (i = 0; i < NUM_THREADS; i++) pthread_create (&thread[i], NULL, parallel_run, (void*)i); for (i = 0; i < NUM_THREADS; i++) pthread_join (thread[i], NULL); SWAP_BOARDS( outboard, inboard ); } } /* * We return the output board, so that we know which one contains * the final result (because we've been swapping boards around). * Just be careful when you free() the two boards, so that you don't * free the same one twice!!! */ return inboard; }
void* parallel_game_of_life (void* arg) { /* HINT: in the parallel decomposition, LDA may not be equal to nrows! */ int inorth; int isouth; int jwest; int jeast; thread_struct *thread = (thread_struct *)arg; char* outboard = thread->outboard; char* inboard = thread->inboard; const int nrows = thread->nrows; const int ncols = thread->ncols; const int gens_max = thread->gens_max; pthread_barrier_t *bar = thread->bar; const int LDA = nrows; /** * dividing up the number of rows between the 4 threads */ int from = (thread->thread_num * nrows) / NUMBER_OF_THREADS; int to_row = ((thread->thread_num + 1) * nrows) / NUMBER_OF_THREADS; int curgen, i, j; /* HINT: you'll be parallelizing these loop(s) by doing a geometric decomposition of the output */ for (curgen = 0; curgen < gens_max; curgen++) { for (i = from; i < to_row; i++) { //Only use mod to calculate inorth and isouth if we're at the boundary if (i == 0 || i == nrows - 1) { inorth = mod (i-1, nrows); isouth = mod (i+1, nrows); } else { inorth = i-1; isouth = i+1; } for (j = 0; j < ncols; j++) { //Only use mod to calculate jwest and jeast if we're at the boundary if (j == 0 || j == ncols - 1) { jwest = mod (j-1, ncols); jeast = mod (j+1, ncols); } else { jwest = j-1; jeast = j+1; } const char neighbor_count = BOARD (inboard, inorth, jwest) + BOARD (inboard, inorth, j) + BOARD (inboard, inorth, jeast) + BOARD (inboard, i, jwest) + BOARD (inboard, i, jeast) + BOARD (inboard, isouth, jwest) + BOARD (inboard, isouth, j) + BOARD (inboard, isouth, jeast); BOARD(outboard, i, j) = alivep (neighbor_count, BOARD (inboard, i, j)); } } pthread_barrier_wait(bar); SWAP_BOARDS( outboard, inboard ); } /* * We return the output board, so that we know which one contains * the final result (because we've been swapping boards around). * Just be careful when you free() the two boards, so that you don't * free the same one twice!!! */ return NULL; }
static void GameListSelectRow(GtkCList *pcl, gint y, gint x, GdkEventButton *pev, gpointer p) { #if USE_BOARD3D BoardData *bd = BOARD( pwBoard )->board_data; #endif gamelistrow *pglr; moverecord *pmr, *pmrPrev = NULL; listOLD *pl; if( x < 1 || x > 2 ) return; pglr = gtk_clist_get_row_data( pcl, y ); if (!pglr) pmr = NULL; else pmr = pglr->apmr[(pglr->fCombined) ? 0 : x - 1]; /* Get previous move record */ if (!pglr->fCombined && x == 2) x = 1; else { y--; x = 2; } pglr = gtk_clist_get_row_data( pcl, y ); if (!pglr) pmrPrev = NULL; else pmrPrev = pglr->apmr[(pglr->fCombined) ? 0 : x - 1]; if (!pmr && !pmrPrev) return; for( pl = plGame->plPrev; pl != plGame; pl = pl->plPrev ) { g_assert( pl->p ); if( pl == plGame->plPrev && pl->p == pmr && pmr->mt == MOVE_SETDICE ) break; if( pl->p == pmrPrev && pmr != pmrPrev ) { /* pmr = pmrPrev; */ break; } else if( pl->plNext->p == pmr ) { /* pmr = pl->p; */ break; } } if( pl == plGame ) /* couldn't find the moverecord they selected */ return; plLastMove = pl; CalculateBoard(); if ( pmr && (pmr->mt == MOVE_NORMAL || pmr->mt == MOVE_SETDICE) ) { /* roll dice */ ms.gs = GAME_PLAYING; ms.anDice[ 0 ] = pmr->anDice[ 0 ]; ms.anDice[ 1 ] = pmr->anDice[ 1 ]; } #if USE_BOARD3D if (display_is_3d(bd->rd)) { /* Make sure dice are shown (and not rolled) */ bd->diceShown = DICE_ON_BOARD; bd->diceRoll[0] = !ms.anDice[0]; } #endif UpdateSetting( &ms.nCube ); UpdateSetting( &ms.fCubeOwner ); UpdateSetting( &ms.fTurn ); UpdateSetting( &ms.gs ); SetMoveRecord( pl->p ); ShowBoard(); }