Processingでリバーシを作る

とりあえずソースだけです。
あとでチュートリアル作る予定です。

```Java
class Cell{
  public int x;
  public int y;
  public int stone;
}
int turnStone = 1;
int gameFinish = 0;
Cell[] cells = new Cell[64];
ArrayList<Cell> canPutList = new ArrayList<Cell>();
void setup(){
  size(600, 600); 
  for(int i=0; i<64; i++){
    int x = i % 8;
    int y = i / 8;
    Cell cell = new Cell();
    cell.x = x;
    cell.y = y;
    cell.stone = 0;
    if(cell.x == 3 && cell.y == 3){
      cell.stone = 1;
    }
    if(cell.x == 4 && cell.y == 4){
      cell.stone = 1;
    }
    if(cell.x == 3 && cell.y == 4){
      cell.stone = 2;
    }
    if(cell.x == 4 && cell.y == 3){
      cell.stone = 2;
    }
    cells[i] = cell;
  }
  updateCanPutList();
}
void draw(){
  background(255);
  drawStage();
  drawStones();
  drawCanPutStones();
  drawUI();
}
void mousePressed(){
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    float _x = 60 * cell.x + 60;
    float _y = 60 * cell.y + 60;
    if(mouseX > _x && mouseX < _x + 60){
      if(mouseY > _y && mouseY < _y + 60){
         if(cell.stone == 0){
           if(canPut(cell.x, cell.y, turnStone)){
             put(cell.x, cell.y, turnStone);
             turnEnd();
           }
         }
      }
    }
  }
}
void drawUI(){
  int whiteCount = 0;
  int blackCount = 0;
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    if(cell.stone == 1){
      whiteCount += 1;
    }
    if(cell.stone == 2){
      blackCount += 1;
    }
  }
  fill(0);
  textAlign(LEFT);
  textSize(24);
  text("WHITE : " + whiteCount, 60, 30);
  textAlign(RIGHT);
  text("BLACK : " + blackCount, width - 60, 30);
  if(gameFinish == 1){
    fill(0, 0, 0, 100);
    rect(0, 0, width, height); 
    textAlign(CENTER, CENTER);
    fill(255);
    textSize(64);
    if(whiteCount > blackCount){
      text("WHITE WIN", width/2, height/2);
    }else if(whiteCount < blackCount){
      text("BLACK WIN", width/2, height/2);
    }else{
      text("DRAW", width/2, height/2);
    }
  }
}
void drawCanPutStones(){
  noStroke();
  for(int i=0; i<canPutList.size(); i++){
    Cell cell = canPutList.get(i);
    float _x = cell.x * 60 + 60;
    float _y = cell.y * 60 + 60;
    _x += 30;
    _y += 30;
    if(turnStone == 1){
      fill(255, 255, 255, 150);
    }
    if(turnStone == 2){
      fill(0, 0, 0, 30);
    }
    
    ellipse(_x, _y, 50, 50);
  }
  stroke(1);
}
boolean canPut(int x, int y, int myStone){
  ArrayList<Cell> flipList = getFlipList(x, y, myStone);
  if(flipList.size() == 0){
    return false;
  }
  return true;
}
void put(int x, int y, int myStone){
  ArrayList<Cell> flipList = getFlipList(x, y, myStone);
  Cell targetCell = getCell(x, y);
  targetCell.stone = myStone;
  for(int i=0; i<flipList.size(); i++){
    Cell cell = flipList.get(i);
    cell.stone = myStone;
  }
}
void turnEnd(){
  turnStone += 1;
  if(turnStone > 2){
    turnStone = 1;
  }
  
  int blankCount = 0;
  for(int i=0; i<cells.length; i++){
     Cell cell = cells[i];
     if(cell.stone == 0){
       blankCount += 1;
     }
  }
  updateCanPutList();
  if(blankCount == 0){
    gameFinish = 1;
  }
  if(gameFinish == 0){
    if(canPutList.size() == 0){
      // 置けないとき
      turnEnd();
    }
  }
}
void updateCanPutList(){
  // canPutListを更新
  canPutList.clear();
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    if(cell.stone > 0){
       continue;
    }
    
    ArrayList<Cell> flipList = getFlipList(cell.x, cell.y, turnStone);
    if(flipList.size() > 0){
       canPutList.add(cell);
    }
  } 
}
ArrayList<Cell> getFlipList(int x, int y, int myStone){
   ArrayList<Cell> list = new ArrayList<Cell>();
   Cell targetCell = getCell(x, y);
   if(targetCell.stone > 0){
     return list;
   }
   PVector[] directions = getDirections();
   for(int i=0; i<directions.length; i++){
     PVector dir = directions[i];
     int dirX = (int)dir.x;
     int dirY = (int)dir.y;
     ArrayList<Cell> chainList = new ArrayList<Cell>();
     chain(chainList, targetCell, dirX, dirY, myStone);
     if(chainList.size() > 0){
       for(int j=0; j<chainList.size(); j++){
         Cell cell = chainList.get(j);
         list.add(cell);
       }
     }
   }
   return list;
}
void chain(ArrayList<Cell> chainList, Cell parent, int dirX, int dirY, int myStone){
   int x = parent.x + dirX;
   int y = parent.y + dirY;
   Cell targetCell = getCell(x, y);
   if(targetCell == null){
     // 空にする
     chainList.clear();
     return;
   }
   if(targetCell.stone == 0){
     // 空にする
     chainList.clear();
     return;
   }
   if(targetCell.stone == myStone){
     // 確定
     return;
   }
   chainList.add(targetCell);
   // 繰り返し
   chain(chainList, targetCell, dirX, dirY, myStone);
}
PVector[] getDirections(){
  PVector[] directions = new PVector[8];
  directions[0] = new PVector(0, 1);
  directions[1] = new PVector(1, 1);
  directions[2] = new PVector(1, 0);
  directions[3] = new PVector(1, -1);
  directions[4] = new PVector(0, -1);
  directions[5] = new PVector(-1, -1);
  directions[6] = new PVector(-1, 0);
  directions[7] = new PVector(-1, 1);
  return directions;
}
Cell getCell(int x, int y){
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    if(cell.x == x && cell.y == y){
      return cell;
    }
  }
  return null;
}
void drawStones(){
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    if(cell.stone > 0){
      float _x = 60 * cell.x + 60;
      float _y = 60 * cell.y + 60;
      _x += 30;
      _y += 30;
      if(cell.stone == 1){
        fill(255);
      }
      if(cell.stone == 2){
        fill(0);
      }
      ellipse(_x, _y, 50, 50);
    }
  } 
}
void drawStage(){
  for(int i=0; i<cells.length; i++){
    Cell cell = cells[i];
    float _x = 60 * cell.x + 60;
    float _y = 60 * cell.y + 60;
    fill(0, 255, 0);
    rect(_x, _y, 60, 60);
  } 
}
```