Toggle key in P5.js - processing

I'd like to use the same key to trigger different events, basically to use it in "toggle" mode.
For example, I'd like that when 'N' is pressed once, it executes noLoop() and when it is pressed again, it then executes loop(), so I could use it as a kind of pause/play key.
for now my code looks like this and of course it doesn't work as the two "if" statements are executed back to back :
function keyTyped(){
let n =0;
if (key == 'n' && n == 0 ){
noLoop();
n = 255;
print(n);
}
if (key == 'n' && n == 255){
print("success");
loop();
n = 0;
}
Thanks !

To make n control looping make these changes:
Move the declaration of n out of the keyTyped function so it will maintain state.
Change the two if conditions to an if else
let n = 0;
let cnt = 0;
function setup() {
createCanvas(600, 600);
}
function draw(){
console.log("looping " + cnt++);
}
function keyTyped(){
if (key == 'n' && n == 0 ){
noLoop();
n = 255;
} else if (key == 'n' && n == 255){
loop();
n = 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>

Related

how to divide the work on MPI-Processes GameOfLife C++

I've bin struggeling for a while with MPI and i am not able to Parallelize GameOfLife in c++ using MPI .
i dont really understand how will i divide the work for each Process , and how will every Process do its work i think i've reached a close End here .
the first block is where the root process initiallize 2D-Array , print it and then send for each process its own part of the work(at least i think so) left elements will be given to the last process .
>>>>
if(rank==0){
for (int h = 0; h < ROWS; h++){
for (int w = 0; w <COLS ; w++){
currentWorld[h][w] = (double(rand()) / RAND_MAX < 0.1) ? 'X' :'.';
}
}
//Recieve subarrays and gather them to be printed
//char recieve_array[][];
for (int h = 0; h < ROWS; h++){ // if the iterate starts before rank zero this Code Block will lead to print that array every time we start iterating and that will lead to faulse results
for (int w = 0; w <COLS ; w++){
std::cout<<currentWorld[h][w];
}
}
char send_array[elements_per_process][COLS]; //create the array that will be sent to each Process
int counter=0;
int rankNum=1;
for(int i=0;i<ROWS;i++){
for(int j=0;j<COLS;j++){
send_array[counter][j]=currentWorld[i][j];// send_array which will be send will be from 0 to elements_per_process -1
}
//when the first array is full that condition will be executed(counter+1==elements_per_process),counter set to zero and then prepare the next array
if(counter+1==elements_per_process)// from zero to elemens_per_process-1
{
//those sends goes to every Process with his part of array to work on it , with Tag 10
MPI_Send(&elements_per_process,1,MPI_INT,rankNum,10,MPI_COMM_WORLD);//send the divided work for each Process
MPI_Send(&send_array,COLS*elements_per_process,MPI_CHAR,rankNum,10,MPI_COMM_WORLD);//send the divided work for each Process
rankNum++;
counter=0;
if(left_elements>0 && rankNum==size-1)
{ //last process deal with the Reminder
int left_elements=ROWS-(elements_per_process*size)
MPI_Send(&left_elements,1,MPI_INT,rankNum,10,MPI_COMM_WORLD);//send the divided work for each Process
MPI_Send(&send_array,COLS*left_elements,MPI_CHAR,rankNum,10,MPI_COMM_WORLD);//send the divided work for each Process
}
}
else{
counter++;
}
}
}
in the second Block i am trying to recieve from each process its own part of work which sent by the root and then count the Neighbors alive to set the next generation
so when i recieve those parts , should i iterate through those subarrays or through the whole original array and each process will just know its own part ? and at the end what should i send back ? the new subarrays from each process to root process , or the new whole array ? i think thats my problem for now , any thing will help because its hard to find some thing that could explain that(if any one knows any resource that could help i will be thankfull)
>>>>
if(rank!=0) {
// Determine the uppder and lower Neighbor for every Processe //
int upperNeighbor = (rank == 1) ? size - 1 : rank-1; //determine the upper rank Neighbor
int lowerNeighbor = (rank == size) ? 1 : rank + 1;//determine the lowerNeighbor
char recieved_array[elements_per_process][COLS];
//Process Recieve his part of work from root Process
//Process Recieve needed Data from other Processes(if the cell is at the top/bottom of Process then it needs data from the next/previous Process)
//Tag for thoose Recieves will be 10
MPI_Recv(&elements_per_process,1,MPI_INT,0,10,MPI_COMM_WORLD,&status);
MPI_Recv(&recieved_array,elements_per_process*COLS,MPI_CHAR,0,10,MPI_COMM_WORLD,&status);
//send top row above
MPI_Send(&currentWorld[1][0], COLS, MPI_CHAR, upperNeighbor,20,MPI_COMM_WORLD);
//send bottom row below
MPI_Send(&currentWorld[elements_per_process][0], COLS, MPI_CHAR, lowerNeighbor, 30, MPI_COMM_WORLD);
//recieve bottom row from below
MPI_Recv(&currentWorld[elements_per_process + 1][0],COLS, MPI_CHAR, lowerNeighbor,30, MPI_COMM_WORLD,&status);
//recieve top row from above
MPI_Recv(&currentWorld[0][0], COLS, MPI_CHAR, upperNeighbor, 20, MPI_COMM_WORLD,&status);
int neighbors=0;
for(int i=0;i<ROWS;i++){// originally for(int i=0;i<elements_per_process;i++)
for(int j=0;i<COLS;j++) {
if(J==0||j==COL-1){
if(j==0){// J==0
// check Neighbors but ignoring the left column
for (int rows = i - 1; rows <=i+ 1; rows++){ //from -1 untill 1
for (int cols = j + 1; cols <= j + 1; cols++){//from -1 untill 1
if (i == rows && j == cols)
{
continue;
}
if (i > -1 && i < ROWS && j > -1 && j < COLS){
if (recieved_array[i][j] == 'X'){
neighbors++;
}
}
}
}
}//J==0
else{ //check the Neighbours but ignoring the right column(COL-1)
for (int rows = i - 1; rows <=i+ 1; rows++){ //from -1 untill 1
for (int cols = j + 1; cols <= j + 1; cols++){//from -1 untill 1
if (i == rows && j == cols)
{
continue;
}
if (i > -1 && i < ROWS && j > -1 && j < COLS){
if (recieved_array[i][j] == 'X'){
neighbors++;
}
}
}
}
}
}
else//if(j!=0 && j!=COL-1){
for (int rows2 = i - 1; rows2 <=i+ 1; rows2++){ //from -1 untill 1
for (int cols2 = j + 1; cols2 <= j + 1; cols2++){//from -1 untill 1
if (i == rows2 && j == cols2)
{
continue;
}
if (i > -1 && i < ROWS && j > -1 && j < COLS){
if (recieved_array[i][j] == 'X'){
neighbors++;
}
}
}
}
}
}
}
}

Minimax Algorithm doesn't work as expected

I'm currently working on a checkers game against an AI in c#. I have tried to implement the AI using minimax algorithm. Although my function works the moves it selects are not logical at all. I tested it with many plays and algorithm just select bad moves when there are many better option. I don't think its due to the horizon problem because the move it makes have immediate consequences such as loosing a piece without capturing any of the opponents piece.
Som notes about the code:
My function takes a 8x8 2d array of enum Pieces which represents the checkers board.
BlackPlayer is a bool value within the same class with function.
MyPiece(currentPiece) function checks if the currentPiece is the same color with the AI.
Since capture is mandatory in checkers function first checks if the gameState contains any capture moves. If not checks normal moves.
I used alpha-beta pruning to make it more efficient.
I used CloneGameState(gameState) function to copy the 2d array so that original array that represents the game never changes.
public int Minimax (Pieces[,] gameState, int depth, bool is_maximizing, int alpha, int beta)
{
//Base Case - Return the board value
if (depth == 3)
return HeuristicEvaluation(gameState);
Move[] possibleMoves;
int bestValue;
bool currentSide;
if (is_maximizing)
{
bestValue = int.MinValue;
currentSide = BlackPlayer;
}
else
{
bestValue = int.MaxValue;
currentSide = !BlackPlayer;
}
// check forced moves
int moveCount = rules.GetCaptureMoves(gameState,out possibleMoves, currentSide);
// if no forced moves get normal moves
if (moveCount < 1)
moveCount = rules.GetNormalMoves(gameState,out possibleMoves, currentSide);
// traverse moves
for (int i = 0; i < moveCount; i++)
{
Pieces[,] newGameState = ApplyMove(CloneGameState(gameState), possibleMoves[i]);
int newStateValue = Minimax(newGameState, depth + 1, !is_maximizing,alpha, beta);
if (is_maximizing)
{
if (newStateValue > bestValue)
{
bestValue = newStateValue;
if (depth == 0)
bestMove = possibleMoves[i];
if (newStateValue > alpha)
alpha = newStateValue;
if (alpha >= beta)
return bestValue;
}
}
//Evaluation for min
else
{
if (newStateValue < bestValue)
{
bestValue = newStateValue;
if (newStateValue < beta)
beta = newStateValue;
if (alpha >= beta)
return bestValue;
}
}
}
return bestValue;
}
The heuristics function:
public int HeuristicEvaluation(Pieces[,] gameState)
{
int stateValue = 0;
//use loops to check each piece
for (int j = 0; j < 8; j++)
{
int i = 0;
if (j % 2 == 1)
i++;
for (; i < 8; i += 2)
{
Pieces currentPiece = gameState[i, j];
if (currentPiece != Pieces.empty)
{
// if the current piece is mine
if (MyPiece(currentPiece))
{
// check if my piece is a king
if (currentPiece == Pieces.whiteKing || currentPiece == Pieces.blackKing)
stateValue += 80;
// my piece is a man
else
{
stateValue += 30;
// row values, closer to king zone higher the value
if (currentPiece == Pieces.blackMan)
{
// black goes in reverse direction
int y = 7-j;
stateValue += y;
}
else
stateValue += j;
}
// pieces on the edge are safe from capture
if (i == 0 ||i == 7 || j== 0 ||j ==7)
{
stateValue += 10;
}
}
// point reduction for enemy pieces
else
{
if (currentPiece == Pieces.whiteKing || currentPiece == Pieces.blackKing)
stateValue -= 80;
else
{
stateValue -= 20;
// row values, closer to king zone higher the value
if (currentPiece == Pieces.blackMan )
{
// black goes in reverse direction
int y = 7-j;
stateValue -= y;
}
else
stateValue -= j;
}
// pieces on the edge cant be captured
if (i == 0 || i == 7 || j == 0 || j == 7)
{
stateValue -= 10;
}
}
}
}
}
return stateValue;
}
First, I want to point out that your functions Maximizer and Minimizer can be combined in one function Minimax(Pieces, gameState, depth, bool is_maximizing) because their logic is almost the same except the couple of lines of code. So instead of calling Maximizer, you will call Minimax with is_maximizing set to true. And instead of calling Minimizer, just call Minimax with is_maximizing set to false. This will help to avoid repetition and will make your code more readable.
This first point leads us to a mistake in the algorithm. In the Minimize function you recursively call itself, while you should call the Maximize function.
Another point is the way you handle all valid moves in the given position. You don't have to separate processing of capture moves from non-capture ones. The reason is once again that the logic for processing both types of moves is the same. I suggest to create two functions - GenerateValidMoves() and SortValidMoves(). GenerateValidMoves() function will generate a list of all valid moves in the given position. After the moves list was generated, call SortValidMoves() to sort the list so that capture moves are located in the beginning of the list followed by non-capture moves.
Here is a simplified pseudocode for minimax:
Minimax(color, board, depth, is_max):
if ((depth == DEPTH_CUTOFF) or IsTerminalNode()):
return EvalBoard()
best_score = is_max ? -infinity : infinity
valid_moves = GenerateValidMoves(board, color)
for curr_move in valid_moves:
clone_board = board.clone()
clone_board.make_move(curr_move)
int curr_score = Minimax(opposite_color, clone_board, depth + 1, !is_max)
if (is_max) {
if (curr_score > best_score) {
best_score = curr_score
best_move = curr_move
}
} else {
if (curr_score < best_score) {
best_score = curr_score
best_move = curr_move
}
}
return best_score

N Queen recursive program

I am trying to solve the n-queen problem (placing n queens on a nxn board without any two queens attacking each other) by defining a function that takes an nxn boolean array of falses and should fill the answer with true where the queens should be. I am getting incorrect answer but can't see why the recursion doesn't work!
bool check(bool ** board, int n, int row, int col){
if(row == 0) return true;
for(int r = 0 ; r < row ; ++r){
if(board[r][col]) return false;
int left = max(col - row + r, 0), right = min(col + row - r, n-1);
if(board[r][left] || board[r][right]) return false;
}
return true;
}
bool queen(bool ** board, int n, int level = 0 ){
for(int col = 0 ; col < n ; ++col){
if( !check(board, n, level, col) ) continue;
board[ level ][ col ] = true;
if( level == n-1 ) return true;
if( queen(board, n, level+1) ) return true;
board[ level ][ col ] = false;
}
return false;
}
in main() i dynamically create bool ** board, and fill it with false, then call queen(board, n).
The weird thing is that it is giving the correct solution except for n=4,6!
Any help is greatly appreciated!
Your fault is the min/max.Operation, so you don't check straight lines.
This should do the trick:
int left = col - row + r;
int right = col + row - r;
if ( left >= 0 && board[r][left] || right < n && board[r][right])
return false;

For-loop in draw() Processing

I put this code in the draw() function in Processing, and it doesn't work. Can someone explain why, and help me fix this? What I want it to do is to cycle through each element of the 2d boolean array and check if it is true or false.
for(int i = 0; i < elemts.length; i++)
{
for(int j = 0; j < elemts[0].length; j++)
{
if(elemts[i][j] == true)
{
rect(i*5,j*5,5,5);
}
}
}
The for loop should be like this
for(start; condition; code to excute every turn)
When you want to skip it you should add a semicolon.
First of all, you didn't add i++ or j++, so the for-loop doesn't run. Next, the draw function runs itself 60 times per second, so putting a for-loop with a certain number of elements doesn't allow the draw() to work. Use the below code instead.
if(elemts[x][y] == true)
{
rect(x*5,y*5,5,5);
fill(0,0,0);
}
if(x < elemts.length)
{
x += 1;
}
if(x == elemts.length)
{
x = 0;
y += 1;
}

How to increment and decrement between two values

This is embarrassing, but:
Let say I want to add 1 to x until it reaches 100. At that point I then want to subtract 1 from x until it reaches 1. Then I want to add 1 to x until it reaches 100, and so on.
Could someone provide some simple pseudocode to this question that is making me feel especially dumb.
Thanks :)
EDIT 1
Apologies! I made my example too simple. I actually will be incrementing using a random number at each iteration, so responses that require (x == 100) would not work as x will surely go above 100 and below 1.
Here is math way:
for(int i=0;i<10000000;i++)
print(abs(i%200-100))
Algo's way:
int i = 1;
while(1)
{
while(i<100)print(i++);
while(i>1)print(--i);
}
Random updated:
int i = 1;
while(1)
{
while(i<100)print(i=min(100,i+random()));
while(i>1)print(i=max(1,i-random()));
}
int ceiling = 100;
int floor = 1;
int x = 1;
int step = GetRandomNumber(); //assume this isn't 0
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
while(x + step <= ceiling) {
x += step;
}
while(x - step >= floor) {
x -= step;
}
}
Or, being more concise (at the risk of being less clear):
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
while((step > 0 && x + step <= ceiling) || (step < 0 && x + step >= floor))
{
x += step;
}
step = step * -1;
}
Alternatively:
while(someArbitraryCuttoffOrAlwaysTrueIDK) {
if((step > 0 && x + step > ceiling) || (step < 0 && x + step < floor))
{
step = step * -1;
}
x += step;
}
C#:
Random rnd = new Random();
int someVarToIncreaseDecrease = 0;
bool increasing = true;
while(true) {
int addSubtractInt = rnd.Next(someUpperBound);
if (increasing && (someVarToIncreaseDecrease + addSubtractInt >= 100))
increasing = false;
else if (!increasing && (someVarToIncreaseDecrease - addSubtractInt < 0))
increasing = true;
if (increasing) {
someVarToIncreaseDecrease += addSubtractInt;
}
else {
someVarToIncreaseDecrease -= addSubtractInt;
}
}

Resources