// go_demo.pde - Go-ishi Model Simulator (Processing port - BASIC logic faithful version) // Maintains the structure and logic of the original BASIC code, with key input wait removed. //[go_demo.bas]***********************************************[Ver 1.00] // Go-ishi model simulator // algo. from M.Ohtsuka // demonstlation mode(including wait loop) // rigid(barrior) mode & retrial mode // special thanks to Dr.M.Matsuzaki // prog.by Y.Okamoto 1992.06/09-1996.12/23,1997.3/14,4/30 // ***************************************************************** // Modified and Ported by Claude ClaudeSonnet4.5 on 25 Dec,2025 // --- Constants and Global Variables (corresponding to BASIC DIM/DEFINT) --- final int BMAX = 8000; final int IMAX = 38; final int JMAX = 24; final int D = 20; // D: Grid spacing final int R = 10; // R: Go stone radius final int IS = 1; // Start I index final int JS = 2; // Start J index (board drawing start position) final int WMAX = 10; // Wait rate (for wait time adjustment) int[][] F = new int[IMAX + 1][JMAX + 1]; // F(I,J): Cell state flag (0:untried, 1:broken/seed, 2:hardened, 3:waiting for trial, 4:seed) int[] N_count = new int[BMAX + 1]; int[] NR_count = new int[BMAX + 1]; int[] RF = new int[BMAX + 1]; // Temporary arrays for cells waiting for trial int[] SI = new int[BMAX]; int[] SJ = new int[BMAX]; int K; // Counter for cells waiting for trial (KMAX) // Temporary arrays for broken cells int[] NI = new int[BMAX]; int[] NJ = new int[BMAX]; int C; // Counter for broken cells (LMAX) float PP; // P.P!: Propagation probability (0.0-1.0) int N = 0; // N: Number of broken cells int NR = 0; // NR: Number of hardened cells int NN = 1; // NN: Trial count (No) int RFG = 0; // RFG: Boundary reached flag int FLG = 0; // FLG: Trial flag (1: destruction occurred) int ST = 1; // ST: Trial stage // --- setup() --- void setup() { // Reserve board maximum size + information display area // If users change numerical values, modify here size(1024,600); surface.setTitle("Go-ishi model simulator (BASIC Replicated)"); // Input propagation probability (corresponds to BASIC line 1282) String input = "0.45"; try { input = javax.swing.JOptionPane.showInputDialog("Hit probability (0.0-1.0)", input); if (input == null) exit(); PP = Float.parseFloat(input); if (PP < 0.0) PP = 0.0f; if (PP > 1.0) PP = 1.0f; } catch (NumberFormatException e) { PP = 0.65f; } dispInit(); // Initialize array F startSimulation(); // Start the first trial } // --- draw() --- void draw() { // Recreate BASIC main loop GOTO logic after line 1420 if (FLG == 1) { // When destruction occurred (equivalent to GOTO 1430 at line 1530) FLG = 0; // Reset flag step1_monteCarloTrial(); // Go to Monte Carlo trial phase } else { // When propagation stopped (line 1540 onwards) // Accumulate results (BASIC 1540-1580) N_count[N] = N_count[N] + 1; NR_count[NR] = NR_count[NR] + 1; if (RFG == 1) RF[N] = RF[N] + 1; displayInfo(); // Display information (BASIC 1560) // Instead of key input wait (BASIC 1590) noLoop(); // Stop automatic execution of draw() delay(1500); // Wait 1.5 seconds // Go to next trial (BASIC 1600-1610) NN++; startSimulation(); loop(); // Resume automatic execution of draw() } } // ----------------------------------------------------------------- // --- Drawing and Initialization --- void drawBoard() { background(255); // White background // Draw cell area (BASIC 1230: color 6=magenta/cyan) fill(200, 200, 200); // Gray as alternative noStroke(); rect(IS * D, JS * D, (IMAX - IS) * D, (JMAX - JS) * D); // Grid lines (BASIC 1240-1280: color 0=black) stroke(0); // Vertical lines for (int i = IS; i <= IMAX; i++) { line(i * D, JS * D, i * D, JMAX * D); } // Horizontal lines for (int j = JS; j <= JMAX; j++) { line(IS * D, j * D, IMAX * D, j * D); } drawCells(); } void drawCells() { for (int i = 1; i <= IMAX; i++) { for (int j = 1; j <= JMAX; j++) { int x = i * D; int y = j * D; if (F[i][j] == 4) { // Seed stone (initial stone) - draw in RED fill(255, 0, 0); stroke(0); ellipse(x, y, R * 2, R * 2); noStroke(); } else if (F[i][j] == 1) { // Broken cell (BASIC 1370: color 5=magenta, 1870: color 3=cyan) // Seed is green, broken cell is blue fill(color(0,0,255) ); ellipse(x, y, R * 2, R * 2); } else if (F[i][j] == 2) { // Hardened cell (BASIC 1940: color 0=black, fill color 1=white) fill(0); stroke(0); ellipse(x, y, R * 2, R * 2); noStroke(); } else if (F[i][j] == 3) { // Waiting for trial (BASIC 1754: color 2=green, radius 2) fill(255, 0, 0); // Red dot ellipse(x, y, 4, 4); } } } } void dispInit() { // BASIC *DISP.INIT (1990-2030) for (int i = 0; i <= IMAX; i++) { for (int j = 0; j <= JMAX; j++) { F[i][j] = 0; } } } void displayInfo() { fill(0); textSize(14); // Display on the right side of the board float baseX = (IMAX + 1) * D + 10; float baseY = JS * D; String info = String.format("Hit probability=%.2f No:%d Broken cells=%d Edge=%d", PP, NN, N, NR); text(info, baseX, baseY + 10); textSize(12); text("Simulation automatically proceeds to next trial.", baseX, baseY + 40); } // ----------------------------------------------------------------- // --- Simulation Control --- void startSimulation() { dispInit(); drawBoard(); // Initialize parameters (BASIC 1350, 1400) N = 0; NR = 0; RFG = 0; K = 0; C = 0; ST = 1; FLG = 0; // Set seed (BASIC 1340-1390) int I = IMAX / 2; int J = JMAX / 2 + 1; // One row down from center N = 1; F[I][J] = 4; // Seed flag (using 4 to distinguish from broken cells) // Draw the seed stone in RED int X = I * D; int Y = J * D; fill(255, 0, 0); // Red stroke(0); ellipse(X, Y, R * 2, R * 2); noStroke(); // Add adjacent cells to waiting for trial list (BASIC 1410) neighborCell(I, J); // Start Monte Carlo trial (BASIC 1430-1470) step1_monteCarloTrial(); } // --- Step 1: Monte Carlo Trial (BASIC 1430-1470) --- void step1_monteCarloTrial() { int KMAX = K; C = 0; // Reset broken cell list counter // Dice roll for all cells in waiting for trial list for (int k = 0; k < KMAX; k++) { int I = SI[k]; int J = SJ[k]; // F=3 is a temporary flag for drawing, and does not need to be returned to F=0 before passing to *DICE sub. // Since *STAT does not register cells with F>0, SI,SJ only contain cells with F=3 or F=0. // By passing F=3 cells directly to *DICE, there is a possibility of being skipped at line 1790 of *DICE, // so here F(I, J) is returned to untried (0) to pass the F>0 check of *DICE. if (F[I][J] == 3) F[I][J] = 0; dice(I, J); waitLoop(WMAX, 1000); } // Move to next propagation (BASIC 1480-1520) int LMAX = C; K = 0; // Reset next waiting for trial list ST = ST + 1; for (int l = 0; l < LMAX; l++) { int I_break = NI[l]; int J_break = NJ[l]; // Propagate from broken cells to adjacent cells neighborCell(I_break, J_break); } } // ----------------------------------------------------------------- // --- Subroutine: Check Adjacent Cells (*NEIGHB, *STAT) --- void neighborCell(int I, int J) { // BASIC *NEIGHB (1650-1680) stat(I, J - 1); stat(I + 1, J); stat(I, J + 1); stat(I - 1, J); } void stat(int P, int Q) { // BASIC *STAT (1720-1760) // Check if out of bounds if (P < IS || Q < JS || P > IMAX || Q > JMAX) { RFG = 1; return; } // Ignore already selected cells (broken:1, hardened:2, waiting:3, seed:4) (BASIC 1740) if (F[P][Q] > 0) { return; } // Register as next waiting for trial point (BASIC 1750) SI[K] = P; SJ[K] = Q; K++; // Draw waiting for trial mark (BASIC 1752-1754) int X = P * D; int Y = Q * D; F[P][Q] = 3; // Set waiting for trial flag fill(255, 0, 0); // Red dot stroke(0); ellipse(X, Y, 4, 4); waitLoop(WMAX, 100); // BASIC 1756 } // --- Subroutine: Monte Carlo Trial (*DICE) --- void dice(int I, int J) { // BASIC *DICE (1780-1960) // barrier mode (BASIC 1790) if (F[I][J] > 0) return; float DI = random(1); // BASIC 1810 waitLoop(WMAX, 1000); // BASIC 1820 if (DI > PP) { // --- rigid cell (hardened) --- (BASIC 1910-1960) int X = I * D; int Y = J * D; // Draw (BASIC 1940: color 0=black, fill color 1=white) fill(0,0,255); stroke(0); ellipse(X, Y, R * 2, R * 2); noStroke(); F[I][J] = 2; // Hardened flag NR++; } else { // --- break cell (broken) --- (BASIC 1840-1900) int X = I * D; int Y = J * D; // Draw (BASIC 1870: color 3=cyan) fill(255); stroke(0); ellipse(X, Y, R * 2, R * 2); NI[C] = I; NJ[C] = J; C++; // Add to broken cell list F[I][J] = 1; // Broken flag FLG = 1; // Destruction occurred N++; } } // --- Wait Loop --- void waitLoop(int wmax, int innerLoop) { int waitTime = wmax * innerLoop / 5000; delay(waitTime); }