Jgrasp Tic Tac Toe Searching A Two Dimensional array - arrays

Today I am creating a Tic-Tac-Toe program using a two dimensional array in Java. I have written most of the code and have my value for the "X" and "O" to be set inside the array. What I cannot seem to figure out is how to search the array to test if there is a winner. My current method was:
if(board[0][0] && board[0][1] && board[0][2] == x)
{
//Some player wins
}
Of course this doesn't bring me the results I had hoped. I would love an explanation on how I can check my array and call a winning method. I kindly ask that it not be completed for me, while this is absolutely much too kind it would also not allow me to further my knowledge. Thank you very much and I hope to hear back from someone soon!
Program:
import java.util.*;
import java.io.*;
import static java.lang.System.*;
public class TicTacToe
{
private String[][]board;
private static final int ROWS = 3;
private static final int COLUMNS = 3;
public TicTacToe()
{
board = new String[ROWS][COLUMNS];
for(int r=0; r<ROWS; r++)
for(int c = 0; c<COLUMNS; c++)
board[r][c] = " "; //fill array with spaces
}
public void set(int r, int c, String player)
{
if (board[r][c].equals(" "))
board[r][c] = player; //place the "x" or "o"
}
/* toString() creates a String representation of board, for example,
|x o|
| x |
| o|
*/
public String toString()
{
String d = ""; //d is the display
for(int r=0; r<ROWS; r++)
{
d = d + "|";
for(int c = 0; c<COLUMNS; c++)
d = d+board[r][c];
d = d + "|\n";
}
return d;
}
/*PseudoCode for winner:
If three of same type match in diagonal, row, column, then return a winner based on what varibale
EX: [0][0] [0][1] [0][2] all are X, therefore player with X wins
*/
public boolean winner(String player)
{
//Return Winner
}
public class TicTacToeDriver
{
public void main(String [] args)
{
Scanner keyboard = new Scanner(System.in);
String player = "x"; //first player
TicTacToe game = new TicTacToe();
boolean done = false;
System.out.println(game);
while (!done)
{
System.out.print("Row for " + player + " (-1 TO EXIT): ");
int row = keyboard.nextInt();
if (row<0) //user wants to end the game
done = true;
else
{
System.out.print("Column for " + player + ": " );
int col = keyboard.nextInt();
game.set(row, col, player);//update board
done = game.winner(player); //check for winner
if(done)
System.out.println("Player " + player + " is the winner");
if(player.equals("x")) //change player
player = "o";
else
player = "x";
}
System.out.println(game); //game over
}
}
}
}

You have to create a table, or some kind of raster.
https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaGame_TicTacToe.html
public static boolean hasWon(int theSeed, int currentRow, int currentCol) {
return (board[currentRow][0] == theSeed // 3-in-the-row
&& board[currentRow][1] == theSeed
&& board[currentRow][2] == theSeed
|| board[0][currentCol] == theSeed // 3-in-the-column
&& board[1][currentCol] == theSeed
&& board[2][currentCol] == theSeed
|| currentRow == currentCol // 3-in-the-diagonal
&& board[0][0] == theSeed
&& board[1][1] == theSeed
&& board[2][2] == theSeed
|| currentRow + currentCol == 2 // 3-in-the-opposite-diagonal
&& board[0][2] == theSeed
&& board[1][1] == theSeed
&& board[2][0] == theSeed);
}

Related

Adding up integer values and using them in different clas

I am making a fun practice script for some review but I have come across some problems. The script uses random numbers to decide between the letters "A, B or C" and when you get a set of 3 shows Yahtzee! on the console. I can get that to work just fine but decided to add how many Yahtzees you got out of 25 as well. Here is what I have so far.
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import ArrayList.EnhancedLoop2;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("TIME TO PLAY JAVA YAHTZEE");
System.out.println("Type 1 when ready");
in.nextInt();
ArrayList<NewClass> al = new ArrayList<NewClass>();
for(int i = 0; i <= 25; i++)
{
NewClass nw = new NewClass();
al.add(nw);
}
for(NewClass enhanced : al)
{
System.out.println("You got " + enhanced.m + " Yahtzees. Good Job");
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class NewClass {
public String a;
public String b;
public String c;
public static int m;
public NewClass()
{
getLetter();
}
public static String getLetter()
{
String rv = "";
System.out.println("");
String a = method1();
String b = method1();
String c = method1();
System.out.println("Your letters are");
System.out.println(a + "\n" + b + "\n" + c);
System.out.print("your set is: " + a + b + c + "\n");
getLetter2(a, b, c);
return rv;
}
public static String getLetter2(String a, String b, String c)
{
String rv = "";
if(a == "A" && b == "A" && c == "A")
{
System.out.println("YAHTZEE!");
}
else if(a == "B" && b == "B" && c == "B")
{
System.out.println("YAHTZEE!");
}
else if(a == "C" && b == "C" && c == "C")
{
System.out.println("YAHTZEE!");
m = yahtzeeCount(a, b, c);
}
return rv;
}
public static String method1()
{
String letter = "";
Random r = new Random();
for(int i = 0; i <= 2; i++)
{
int cv = r.nextInt(9) + 1;
if(cv <= 3)
{
letter = "A";
}
else if(cv >= 4 && cv <= 6)
{
letter = "B";
}
else if(cv >=7 && cv <=9)
{
letter = "C";
}
}
return letter;
}
public static int yahtzeeCount(String a, String b, String c)
{
int rv = 0;
if(a == "A" && b == "A" && c == "A" || a == "B" && b == "B" && c == "B" || a == "C" && b == "C" && c == "C")
{
rv = 1;
}
return rv;
}
}
I am also having a problem with the script showing "you got # yahtzees. Good job." 25 times instead of once and I can't seem to figure out how to make it show only once.
All help is much appreciated. Thank You.
I ended up changing the script quite a bit and in the end had no need for an ArrayList(I didn't really understand enhanced loops). Here is what I ended up with
package Yahtzee;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("TIME TO PLAY JAVA YAHTZEE");
System.out.println("Type 1 when ready");
in.nextInt();
for(int i = 0; i <= 25; i++)
{
Test2 nw = new Test2();
}
System.out.println("Congratulations you got " + Test2.rv + " Yahtzees");
}
}
package Yahtzee;
import java.util.Random;
public class Test2 {
public String a;
public String b;
public String c;
public static int rv;
public Test2()
{
System.out.println("");
a = method1();
b = method1();
c = method1();
System.out.println("Your letters are");
System.out.println(a + "\n" + b + "\n" + c);
System.out.print("your set is: " + a + b + c + "\n");
if(a == "A" && b == "A" && c == "A")
{
System.out.println("YAHTZEE!");
rv = (rv + 1);
}
else if(a == "B" && b == "B" && c == "B")
{
System.out.println("YAHTZEE!");
rv = (rv + 1);
}
else if(a == "C" && b == "C" && c == "C")
{
System.out.println("YAHTZEE!");
rv = (rv + 1);
}
}
public static String method1()
{
String letter = "";
Random r = new Random();
for(int i = 0; i <= 2; i++)
{
int cv = r.nextInt(9) + 1;
if(cv <= 3)
{
letter = "A";
}
else if(cv >= 4 && cv <= 6)
{
letter = "B";
}
else if(cv >=7 && cv <=9)
{
letter = "C";
}
}
return letter;
}
}

Cell Compete Problems

Here is my assignment:
There is a colony of 8 cells arranged in a straight line where each day every cell competes with its adjacent cells(neighbour). Each day, for each cell, if its neighbours are both active or both inactive, the cell becomes inactive the next day,. otherwise itbecomes active the next day.
Assumptions: The two cells on the ends have single adjacent cell, so
the other adjacent cell can be assumsed to be always inactive. Even
after updating the cell state. consider its pervious state for
updating the state of other cells. Update the cell informationof
allcells simultaneously.
Write a fuction cellCompete which takes takes one 8 element array of
integers cells representing the current state of 8 cells and one
integer days representing te number of days to simulate. An integer
value of 1 represents an active cell and value of 0 represents an
inactive cell.
Program:
int* cellCompete(int* cells,int days)
{
//write your code here
}
//function signature ends
Test Case 1:
INPUT:
[1,0,0,0,0,1,0,0],1
EXPECTED RETURN VALUE:
[0,1,0,0,1,0,1,0]
Test Case 2:
INPUT:
[1,1,1,0,1,1,1,1,],2
EXPECTED RETURN VALUE:
[0,0,0,0,0,1,1,0]
This is the problem statement given above for the problem. The code which I have written for this problem is given below. But the output is coming same as the input.
#include<iostream>
using namespace std;
// signature function to solve the problem
int *cells(int *cells,int days)
{ int previous=0;
for(int i=0;i<days;i++)
{
if(i==0)
{
if(cells[i+1]==0)
{
previous=cells[i];
cells[i]=0;
}
else
{
cells[i]=0;
}
if(i==days-1)
{
if(cells[days-2]==0)
{
previous=cells[days-1];
cells[days-1]=0;
}
else
{
cells[days-1]=1;
}
}
if(previous==cells[i+1])
{
previous=cells[i];
cells[i]=0;
}
else
{
previous=cells[i];
cells[i]=1;
}
}
}
return cells;
}
int main()
{
int array[]={1,0,0,0,0,1,0,0};
int *result=cells(array,8);
for(int i=0;i<8;i++)
cout<<result[i];
}
I am not able to get the error and I think my logic is wrong. Can we apply dynamic programming here If we can then how?
private List<Integer> finalStates = new ArrayList<>();
public static void main(String[] args) {
// int arr[] = { 1, 0, 0, 0, 0, 1, 0, 0 };
// int days = 1;
EightHousePuzzle eightHousePuzzle = new EightHousePuzzle();
int arr[] = { 1, 1, 1, 0, 1, 1, 1, 1 };
int days = 2;
eightHousePuzzle.cellCompete(arr, days);
}
public List<Integer> cellCompete(int[] states, int days) {
List<Integer> currentCellStates = Arrays.stream(states).boxed().collect(Collectors.toList());
return getCellStateAfterNDays(currentCellStates, days);
}
private List<Integer> getCellStateAfterNDays(List<Integer> currentCellStates, int days) {
List<Integer> changedCellStates = new ArrayList<>();
int stateUnoccupied = 0;
if (days != 0) {
for (int i1 = 0; i1 < currentCellStates.size(); i1++) {
if (i1 == 0) {
changedCellStates.add(calculateCellState(stateUnoccupied, currentCellStates.get(i1 + 1)));
} else if (i1 == 7) {
changedCellStates.add(calculateCellState(currentCellStates.get(i1 - 1), stateUnoccupied));
} else {
changedCellStates
.add(calculateCellState(currentCellStates.get(i1 - 1), currentCellStates.get(i1 + 1)));
}
}
if (days == 1) {
System.out.println("days ==1 hit");
finalStates = new ArrayList<>(changedCellStates);
return finalStates;
}
days = days - 1;
System.out.println("Starting recurssion");
getCellStateAfterNDays(changedCellStates, days);
}
return finalStates;
}
private int calculateCellState(int previousLeft, int previousRight) {
if ((previousLeft == 0 && previousRight == 0) || (previousLeft == 1 && previousRight == 1)) {
// the state gets now changed to 0
return 0;
}
// the state gets now changed to 0
return 1;
}
Here is my solution in Java:
public class Colony
{
public static int[] cellCompete(int[] cells, int days)
{
int oldCell[]=new int[cells.length];
for (Integer i = 0; i < cells.length ; i++ ){
oldCell[i] = cells[i];
}
for (Integer k = 0; k < days ; k++ ){
for (Integer j = 1; j < oldCell.length - 1 ; j++ ){
if ((oldCell[j-1] == 1 && oldCell[j+1] == 1) || (oldCell[j-1] == 0 && oldCell[j+1] == 0)){
cells[j] = 0;
} else{
cells[j] = 1;
}
}
if (oldCell[1] == 0){
cells[0] = 0;
} else{
cells[0] = 1;
}
if (oldCell[6] == 0){
cells[7] = 0;
} else{
cells[7] = 1;
}
for (Integer i = 0; i < cells.length ; i++ ){
oldCell[i] = cells[i];
}
}
return cells;
}
}
Your program does not distinguish between the number of days to simulate and the number of cells.
#include <bits/stdc++.h>
using namespace std;
int* cellCompete(int* cells,int days)
{
for(int j=0; j<days; j++)
{
int copy_cells[10];
for(int i=1; i<9; i++)
copy_cells[i]=cells[i-1];
copy_cells[0]=0;copy_cells[9]=0;
for(int i=0; i<8; i++)
cells[i]=copy_cells[i]==copy_cells[i+2]?0:1;
}
return cells;
}
int main()
{
int arr[8]={1,1,1,0,1,1,1,1};
int arr2[8]={1,0,0,0,0,1,0,0};
cellCompete(arr2,1);
for(int i=0; i<8; i++)
{
cout<<arr2[i]<<" ";
}
}
Here's some sweet little python code:
def cell(arr, days):
new = arr[:] #get a copy of the array
n = len(arr)
if n == 1: print [0] #when only 1 node, return [0]
for _ in range(days):
new[0] = arr[1] #determine the edge nodes first
new[n - 1] = arr[n - 2]
for i in range(1, n-1):
new[i] = 1 - (arr[i-1] == arr[i+1]) #logic for the rest nodes
arr = new[:] #update the list for the next day
return new
arr = [1, 1, 1, 0, 1, 1, 1, 1]
days = 2
print cell(arr, days)
You can easily do this in Javascript with few lines of code
let cells = [1,1,1,0,1,1,1,1];
let numOfDays = 2;
let changeState = (cellarr)=> cellarr.map((cur, idx, arr)=> (arr[idx-1] ||0) + (arr[idx+1] || 0)===1?1:0);
let newCells =cells;
for (let i = 0 ; i <numOfDays; i++) newCells = changeState(newCells);
console.log(newCells);
This is a C# version of a possible answer. I really struggled with this for a while for some reason!
I also incorporated some of Janardan's stuff above as it helped spur me in the right direction. (cheers!)
The tricky part of the question was dealing with the fact that you had to persist the state of the cell to figure out the next cell competition which I had originally tried with a second array which was messy.
Note: I chose to use the Array.Copy method as I believe it is slightly more efficient and a lot more readable than copying arrays with a for loop when reading through.
Hopefully this helps someone out in the future!
public int[] cellCompete(int[] cell, int day)
{
//First create an array with an extra 2 cells (these represent the empty cells on either end)
int[] inputArray = new int[cell.Length + 2];
//Copy the cell array into the new input array leaving the value of the first and last indexes as zero (empty cells)
Array.Copy(cell, 0, inputArray, 1, cell.Length);
//This is cool I stole this from the guy above! (cheers mate), this decrements the day count while checking that we are still above zero.
while (day-- > 0)
{
int oldCellValue = 0;
//In this section we loop through the array starting at the first real cell and going to the last real cell
//(we are not including the empty cells at the ends which are always inactive/0)
for (int i = 1; i < inputArray.Length - 1; i++)
{
//if the cells below and above our current index are the same == then the target cell will be inactive/0
//otherwise if they are different then the target cell will be set to active/1
//NOTE: before we change the index value to active/inactive state we are saving the cells oldvalue to a variable so that
//we can use that to do the next "cell competition" comparison (this fulfills the requirement to update the values at the same time)
if (oldCellValue == inputArray[i + 1])
{
oldCellValue = inputArray[i];
inputArray[i] = 0;
}
else
{
oldCellValue = inputArray[i];
inputArray[i] = 1;
}
}
}
//Finally we create a new output array that doesn't include the empty cells on each end
//copy the input array to the output array and Bob's yer uncle ;)...(comments are lies)
int[] outputArray = new int[cell.Length];
Array.Copy(inputArray, 1, outputArray, 0, outputArray.Length);
return outputArray;
}
With C#
public static int[] cellCompete(int[] states, int days)
{
if (days == 0) return states;
int leftValue = 0;
int rigthValue = 0;
for (int i = 0; i < states.Length; i++)
{
if (i == states.Length - 1)
rigthValue = 0;
else
rigthValue = states[i + 1];
if (leftValue == rigthValue){
leftValue = states[i];
states[i] = 0;
}
else{
leftValue = states[i];
states[i] = 1;
}
}
cellCompete(states, days - 1);
return states;
}
I think some of the answers above could be more readable (in addition to being more efficient). Use an additional array and alternate updates between them depending on the number of days. You can return the most recently updated array, which will always be the correct one. Like this:
function cellCompete(states, days) {
const newStates = [];
let originalStates = true;
while (days--) {
changeStates(
originalStates ? states : newStates,
originalStates ? newStates : states,
states.length
);
originalStates = !originalStates;
}
return originalStates ? states : newStates;
}
function changeStates(states, newStates, len) {
newStates[0] = !states[1] ? 0 : 1;
newStates[len-1] = !states[len-2] ? 0 : 1;
for (let i = 1; i < len - 1; i++) {
newStates[i] = states[i-1] === states[i+1] ? 0 : 1;
}
}
Here is my solution in c++ using bitwise operators :
#include <iostream>
using namespace std;
void cellCompete( int *arr, int days )
{
int num = 0;
for( int i = 0; i < 8; i++ )
{
num = ( num << 1 ) | arr[i];
}
for( int i = 0; i < days; i++ )
{
num = num << 1;
num = ( ( ( num << 1 ) ^ ( num >> 1 ) ) >> 1 ) & 0xFF;
}
for( int i = 0; i < 8; i++ )
{
arr[i] = ( num >> 7 - i ) & 0x01;
}
}
int main()
{
int arr[8] = { 1, 0, 0, 0, 0, 1, 0, 0};
cellCompete( arr, 1 );
for(int i = 0; i < 8; i++)
{
cout << arr[i] << " ";
}
}
#include <stdio.h>
int main() {
int days,ind,arr[8],outer;
for(ind=0;ind<8;scanf("%d ",&arr[ind]),ind++); //Reading the array
scanf("%d",&days);
int dupArr[8];
for(outer=0;outer<days;outer++){ //Number of days to simulate
for(ind=0;ind<8;ind++){ //Traverse the whole array
//cells on the ends have single adjacent cell, so the other adjacent cell can be assumsed to be always inactive
if(ind==0){
if(arr[ind+1]==0)
dupArr[ind]=0;
else
dupArr[ind]=1;
}
else if(ind==7){
if(arr[ind-1]==0)
dupArr[ind]=0;
else
dupArr[ind]=1;
}
else{
if((arr[ind-1]==0&&arr[ind+1]==0) || (arr[ind-1]==1&&arr[ind+1]==1)){// if its neighbours are both active or both inactive, the cell becomes inactive the next day
dupArr[ind]=0;
}
else //otherwise it becomes active the next day
dupArr[ind]=1;
}
}
for(ind=0;ind<8;ind++){
arr[ind]=dupArr[ind]; //Copying the altered array to original array, so that we can alter it n number of times.
}
}
for(ind=0;ind<8;ind++)
printf("%d ",arr[ind]);//Displaying output
return 0;
}
Here is my code which i had created some months ago,
You want to create two different arrays, because altering same array element will gives you different results.
func competeCell(cell []uint, days uint) []uint{
n := len(cell)
temp := make([]uint, n)
for i :=0; i < n; i ++ {
temp[i] = cell[i]
}
for days > 0 {
temp[0] = 0 ^ cell[1]
temp[n-1] = 0 ^ cell[n-2]
for i := 1; i < n-2 +1; i++ {
temp[i] = cell[i-1] ^ cell[i +1]
}
for i:=0; i < n; i++ {
cell[i] = temp[i]
}
days -= 1
}
return cell
}
Using c++
#include <list>
#include <iterator>
#include <vector>
using namespace std;
vector<int> cellCompete(int* states, int days)
{
vector<int> result1;
int size=8;
int list[size];
int counter=1;
int i=0;
int temp;
for(int i=0;i<days;i++)//computes upto days
{
vector<int> result;
if(states[counter]==0)
{
temp=0;
list[i]=temp;
//states[i]=0;
result.push_back(temp);
}
else
{
temp=1;
list[i]=temp;
result.push_back(temp);
}
for(int j=1;j<size;j++)
{
if(j==size)
{
if(states[j-1]==0)
{
temp=0;
list[j]=temp;
//states[i]=1;
result.push_back(temp);
}
else
{
temp=1;
list[i]=temp;
//states[i]=1;
result.push_back(temp);
}
}
else if(states[j-1]==states[j+1])
{
temp=0;
list[j]=temp;
//states[i]=1;
result.push_back(temp);
}
else
{
temp=1;
list[j]=temp;
//states[i]=1;
result.push_back(temp);
}
}
result1=result;
for(int i=0;i<size;i++)
{
states[i]=list[i];
}
}
return result1;
}
Java solution
This is solution is Java, which will work any number of Cells and any number of days .
public class Solution
{
public List<Integer> cellCompete(int[] states, int days)
{
List<Integer> inputList = new ArrayList<Integer>();
List<Integer> finalList = new ArrayList<Integer>();
// Covert integer array as list
for (int i :states)
{
inputList.add(i);
}
// for loop for finding status after number of days.
for(int i=1; i<= days; i++)
{
if(i==1)
{
finalList = nextDayStatus(inputList);
}
else
{
finalList = nextDayStatus(finalList);
}
}
return finalList;
}
// find out status of next day, get return as list
public List<Integer> nextDayStatus(List<Integer> input)
{
List<Integer> output = new ArrayList<Integer>();
input.add(0,0);
input.add(0);
for(int i=0; i < input.size()-2; i++)
{
if (input.get(i) == input.get(i+2))
{
output.add(0);
}
else
{
output.add(1);
}
}
return output;
}
}
I know this has been answered, but I gave it a go in Java and am pretty sure it will work for any size states array along with number of days:
public class CellCompete {
public static List<Integer> cellCompete(int[] states, int days) {
List<Integer> resultList = new ArrayList<>();
int active = 1, inactive = 0;
int dayCount = 1;
// Execute for the given number of days
while (days > 0) {
int[] temp = new int[states.length];
System.out.print("Day " + dayCount + ": ");
// Iterate through the states array
for (int i = 0; i < states.length; i++) {
// Logic for first end cell
if (i == 0) {
temp[i] = states[i + 1] == active ? active : inactive;
resultList.add(temp[i]);
System.out.print(temp[i] + ", ");
}
// Logic for last end cell
if (i == states.length - 1) {
temp[i] = states[i - 1] == active ? active : inactive;
resultList.add(temp[i]);
System.out.println(temp[i]);
}
// Logic for the in between cells
if (i > 0 && i < states.length - 1) {
if ((states[i - 1] == active && states[i + 1] == active) || (states[i - 1] == inactive && states[i + 1] == inactive)) {
temp[i] = inactive;
} else {
temp[i] = active;
}
resultList.add(temp[i]);
System.out.print(temp[i] + ", ");
}
}
dayCount++;
days--;
// Reset the states array with the temp array
states = temp;
}
return resultList;
}
public static void main(String[] args) {
int[] states = {1, 1, 0, 1, 0, 1, 0, 0};
int days = 5;
// Total of 40
System.out.println(cellCompete(states, days) );
}
}
Where did the people who wanted optimized solutions go?
def Solution(states, days):
for i in range(days):
for j in range(len(states)):
if (j == 0):
states[i] = states[1]
elif (j == len(states)-1):
states[i] = states[-2]
else:
states[i] = abs(states[i-1] - states[i+1])
return states
By definition, all the cells, including non-existent ones, are in fact booleans:
var cellUpdate = (cells, days) => {
let result = [];
// update states
for(let i = 0; i < cells.length; i++) result.push((!Boolean(cells[i-1]) === !Boolean(cells[i+1])) ? 0 : 1) ;
// repeat for each day
if (days > 1) result = cellUpdate(result, days - 1);
return result;
Here is the best python Solution
value=input()
n=int(input())
lst=[]
for i in value:
if "1"in i:
lst.append(1)
elif "0" in i:
lst.append(0)
for _ in range(n):
store = []
for i in range(8):
if i==0:
store.append(lst[i+1])
elif i==7:
store.append(lst[i-1])
elif lst[i-1]==lst[i+1]:
store.append(0)
else:
store.append(1)
lst=store
print(store)
Scala solution:
def cellDayCompete(cells: Seq[Int]): Seq[Int] = {
val addEdges = 0 +: cells :+ 0
(addEdges.dropRight(2) zip addEdges.drop(2)).map {
case (left, right) =>
(left - right).abs
}
}
def cellCompete(cells: Seq[Int], days: Int): Seq[Int] = {
if (days == 0) {
cells
} else {
cellCompete(cellDayCompete(cells), days - 1)
}
}
A code run with the example above can be found at Scastie
Just answered this question today and here was my solution in python3
def cellCompete(states, days):
for i in range(0, days):
#this is where we will hold all the flipped states
newStates = []
'''
Algo: if neigbors are the same, append 0 to newStates
if they are different append 1 to newStates
'''
for currState in range(len(states)):
#left and right ptr's
left = currState - 1
right = currState + 1
#if at beginning of states, left is automatically inactive
if left < 0:
if states[right] == 1:
newStates.append(1)
else:
newStates.append(0)
#if at end of states, right is automatically inactive
elif right > 7: #we know there is always only 8 elems in the states list
if states[left] == 1:
newStates.append(1)
else
newStates.append(0)
#check to see if neighbors are same or different
elif states[left] != states[right]:
newStates.append(1)
else:
newStates.append(0)
#Set the states equal to the new flipped states and have it loop N times to get final output.
states = newStates
return states
def cellCompete(states, days):
d = 0
l = len(states)
while d < days:
new_states = [0] * l
for i in range(l):
if i == 0 and states[i+1] == 0 or i == l - 1 and states[i-1] == 0:
new_states[i] = 0
elif i == 0 and states[i+1] == 1 or i == l - 1 and states[i-1] == 1:
new_states[i] = 1
elif states[i+1] == states[i-1]:
new_states[i] = 0
else:
new_states[i] = 1
states = new_states
d = d + 1
return states
static int[] CellCompete(int[] states, int days)
{
int e = states.Length;
int[] newStates = new int[(e+2)];
newStates[0] = 0;
newStates[e+1] = 0;
Array.Copy(states, 0, newStates, 1, e);
for (int d = 0; d < days; d++)
{
states = Enumerable.Range(1, e).Select(x => newStates[x - 1] ^ newStates[x + 1]).ToArray();
newStates[0] = 0;
newStates[e + 1] = 0;
Array.Copy(states, 0, newStates, 1, e);
}
return states;
}
//Here is a working solution for this problem in C#
public class HousesinSeq
{
private string _result;
public string Result
{
get { return _result; }
}
public void HousesActivation(string houses, int noOfDays)
{
string[] housesArr = houses.Split(' ');
string[] resultArr = new string[housesArr.Length];
for (int i = 0; i < noOfDays; i++)
{
for (int j = 0; j < housesArr.Length; j++)
{
if (j == 0)
{
if (housesArr[j + 1] == "0")
{
resultArr[j] = "0";
}
else
{
resultArr[j] = "1";
}
}
else if (j == housesArr.Length - 1)
{
if (housesArr[j - 1] == "0")
{
resultArr[j] = "0";
}
else
{
resultArr[j] = "1";
}
}
else
{
if (housesArr[j + 1] == housesArr[j - 1])
{
resultArr[j] = "0";
}
else
{
resultArr[j] = "1";
}
}
}
resultArr.CopyTo(housesArr, 0);
}
foreach (var item in resultArr)
{
//Console.Write($"{item} ");
_result += item + " ";
}
_result = _result.Trim();
}
}
public class Colony {
public static int[] cellCompete(int[] cell, int day) {
int[] ar = new int[10];
for(int i=1; i<9; i++) {
ar[i] = cell[i-1];
}
while(day-- >0) {
int temp = 0;
for(int i=1; i<9; i++) {
if(Math.abs(temp-ar[i+1])==1) {
temp = ar[i];
ar[i] = 1;
}
else {
temp = ar[i];
ar[i] = 0;
}
}
}
return ar;
}
public static void main(String[] args) {
int[] cell = {1,0,1,1,0,1,0,1};
int day = 1;
cell = cellCompete(cell, day);
for(int i=1; i<9; i++) {
System.out.print(cell[i]+" ");
}
}
}

Actionscript 3 - How to Check if an Array Position Already Exists

Hello my question is as stated. I have a randomly generated dungeon with a player and random blocks. All the rooms in the dungeon are saved in the ROOMS 2D array which contains the data for the rooms. You have a current Row and current Col which is where the player is at. What i need to know is how to say IF there is no room above the current position then change the outside wall graphic to close the exits/doors where there is no room. I have this somewhat working but everyway i change it there is always one room which just will not work if i try to add the code. What i have now is abunch of if statements saying IF ROOMS[currentRow + 1][currentCol](< that would be equal to down) so if one row up exists then change the graphic by doing gotoAndStop. So how or which is the best way to determine if a position exists because with this, it will randomly comeback with errors like "term is undefined and has no properties." Also i have really dirty code, sorry im new, ill try to clean it up later but if any of you feel like it, i wont stop you haha!
Im grateful for any replies! Here is my room class
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Room extends MovieClip{
var room1:Array = new Array();
var room2:Array = new Array();
var room3:Array = new Array();
var room4:Array = new Array();
var room5:Array = new Array();
var room6:Array = new Array();
var room7:Array = new Array();
var room8:Array = new Array();
var room9:Array = new Array();
var room10:Array = new Array();
var currentRow:int = 0;
var currentCol:int = 0;
var box:Box;
var boxes:Array;
var ROOMS:Array;
var onTop:Boolean;
var moved:Boolean;
private var player:Player;
private var walls:Walls;
private var blocker1:Blocker;
private var blocker2:Blocker;
private var blocker3:Blocker;
private var blocker4:Blocker;
private var arrowImage:ArrowSymbol;
public function Room(){
init();
createRooms();//add the walls + boxes of first room to the first array value // later make floors array that contains all the rooms and room array that contains all the boxes and enemies + events
stage.addChild(ROOMS[currentRow][currentCol]);
Constants.wallsRef = ROOMS[currentRow][currentCol];
addEventListener(Event.ENTER_FRAME, update);
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}
function init(){
Constants.stageRef=stage;
player = new Player();
//add walls
walls = new Walls();
Constants.wallsRef=walls;
blocker1 = new Blocker();//BLOCKER WHEN PLAYER TOUCHES IT CHANGES ROOM
blocker1.x = 350;
blocker1.y = 1;
stage.addChild(blocker1);
blocker2 = new Blocker();
blocker2.x = 350;
blocker2.y = 619;
stage.addChild(blocker2);
blocker3 = new Blocker();
blocker3.x = -30;
blocker3.y = 300;
blocker3.rotation = 90;
stage.addChild(blocker3);
blocker4 = new Blocker();
blocker4.x = 700;
blocker4.y = 300;
blocker4.rotation = 90;
stage.addChild(blocker4);
Constants.blockerRef1 = blocker1;
Constants.blockerRef2 = blocker2;
Constants.blockerRef3 = blocker3;
Constants.blockerRef4 = blocker4;
//add player
player.x = 300;
player.y = 200;
stage.addChild(player);
arrowImage = new ArrowSymbol();
arrowImage.x = 630;
arrowImage.y = 30;
box = new Box();
boxes = new Array();
ROOMS = new Array([room2],
[room6, room1, room5], /// THIS IS THE MAP OF THE FLOOR /// GOING UP ON THE GAME IS GOING DOWN ON IT
[room7, room8],
[room3, room9],
[room4]);//THIS WILL EVENTUALLY BE COMPLETELY RANDOMIZED//
onTop = false;
moved = false;
}
function update(e:Event){
arrowCount.text = " " + Constants.arrowNumRef;//arrow amount left
closeUnnecessaryExits();
//UP
if(Constants.blockerRef1.hitTestPoint(player.x,player.y) && moved != true){
stage.removeChild(ROOMS[currentRow][currentCol]);//remove the room you are in so the new room doesnt overlap
currentRow++;//change where the player is in
stage.addChild(ROOMS[currentRow][currentCol]);//add new room
Constants.wallsRef = ROOMS[currentRow][currentCol];//add colision
player.y = 600;
stage.addChild(arrowCount);
stage.addChild(arrowImage);
trace();
moved = true;
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//DOWN
if(Constants.blockerRef2.hitTestPoint(player.x,player.y) && moved != true){
//this will be where i want to change rooms
stage.removeChild(ROOMS[currentRow][currentCol]);
currentRow--;
Constants.wallsRef = ROOMS[currentRow][currentCol];
stage.addChild(ROOMS[currentRow][currentCol]);
player.y = 10;//change to 600
moved = true;
trace("changed rooms");
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//LEFT
if(Constants.blockerRef3.hitTestPoint(player.x,player.y) && moved != true){
stage.removeChild(ROOMS[currentRow][currentCol]);//remove the room you are in so the new room doesnt overlap
currentCol--;//change where the player is in
stage.addChild(ROOMS[currentRow][currentCol]);//add new room
Constants.wallsRef = ROOMS[currentRow][currentCol];//add colision
player.x = 600;
stage.addChild(arrowCount);
stage.addChild(arrowImage);
moved = true;
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
//RIGHT
if(Constants.blockerRef4.hitTestPoint(player.x,player.y) && moved != true){
//this will be where i want to change rooms
stage.removeChild(ROOMS[currentRow][currentCol]);
currentCol++;
Constants.wallsRef = ROOMS[currentRow][currentCol];
stage.addChild(ROOMS[currentRow][currentCol]);
player.x = 10;//change to 600
moved = true;
trace("changed rooms");
stage.addChild(arrowCount);
stage.addChild(arrowImage);
}else if(Constants.playerRef.hitTestObject(Constants.blockerRef1) == false && moved == true){
moved = false;
}
}
function createRooms(){
for(var r = 0; r <ROOMS.length; r++){
walls = new Walls();
addRandomBlocks();
for(var c = 0; c < ROOMS[r].length; c++){
walls = new Walls();
addRandomBlocks();
ROOMS[r][c] = walls;
}
trace(ROOMS[r][c]);
}
}
// [room2, NaN],
// [room6, room1, room5], /// THIS IS THE MAP OF THE FLOOR /// GOING UP ON THE GAME IS GOING DOWN ON IT
// [room7, room8],
// [room3, room9],
// [room4]);
function closeUnnecessaryExits(){
trace("ROW: " + currentRow + " COL: " + currentCol);
var up = ROOMS[currentRow + 1];
var down = ROOMS[currentRow - 1];
var right = ROOMS[currentRow][currentCol + 1];
var left = ROOMS[currentRow][currentCol - 1];
//check to see which outside wasall to use
if(ROOMS[currentRow + 1] == null && up && right && left){
ROOMS[currentRow][currentCol].gotoAndStop(2);
}else if(down == null && left == null && right && up){
ROOMS[currentRow][currentCol].gotoAndStop(3);
}else if(down == null && left == null && up == null && right){
ROOMS[currentRow][currentCol].gotoAndStop(4);
}else if(left == null && down && right && up){// IF HAVING PROBLEMS THEN MAKE THIS MAKE SURE ALL OTHER SIDES ARE TRUE
ROOMS[currentRow][currentCol].gotoAndStop(5);
}else if(down == null && left == null && right == null && up){
ROOMS[currentRow][currentCol].gotoAndStop(6);
}else if(down && up == null && right == null && left == null){
ROOMS[currentRow][currentCol].gotoAndStop(7);
}else if(ROOMS[currentRow + 1][currentCol] == null && ROOMS[currentRow - 1][currentCol] && left && right){
ROOMS[currentRow][currentCol].gotoAndStop(8);
trace("works 1");
}else if(left && right && ROOMS[currentRow - 1][currentCol] == null && ROOMS[currentRow + 1][currentCol] == null){
ROOMS[currentRow][currentCol].gotoAndStop(9);
trace("works 2");
}else if(left && ROOMS[currentRow - 1][currentCol] && right == null && ROOMS[currentRow + 1][currentCol] == null){
ROOMS[currentRow][currentCol].gotoAndStop(10);// LEFT DOWN
trace("works 3");
}else if(left && ROOMS[currentRow + 1][currentCol] && ROOMS[currentRow - 1][currentCol] == null && right == null){
ROOMS[currentRow][currentCol].gotoAndStop(11);//BROKEN left up
trace("working 4");
}else if(left && ROOMS[currentRow + 1][currentCol] == null && ROOMS[currentRow - 1][currentCol] == null && right == null){
ROOMS[currentRow][currentCol].gotoAndStop(12);
trace("works 5");
}else if(right == null && left && up && down){
ROOMS[currentRow][currentCol].gotoAndStop(13);
trace("works 6");
}
}
function addRandomBlocks(){
for(var e=0; e <Math.random() * 10; e++){
//trace("started block");
box = new Box();
box.x = Math.random() * (615 - 100) + 100;
box.y = Math.random() * (500 - 120) + 120;
//colision for block to block
for(var col = 0; col < boxes.length; col++){
if(box.hitTestObject(boxes[col])){
onTop = false;/// THIS NEEDS TO BE TRUE FOR THE DETECTION TO WORK
//trace("THIS BOX IS ON TOP OF ANOTHER");
}
}
if(onTop == false){
boxes.push(box);
walls.addChild(box);
trace("BOX CREATED " + onTop);
//trace(boxes);
}
}
}
}
}
You could streamline your code by creating some simple functions that deal with assigning and accessing values in your 2D array. One that checks if an element within a 2D array exists might look like:
function cellExists(array:Array, x:int, y:int):Boolean {
return array[y] !== undefined && array[y][x] !== undefined;
}
Used like, in your example:
if (cellExists(ROOMS, currentCol, currentRow)) {
//
}
Although with this type of task you would benefit greatly from implementing a class that handles grid + cell data, something along the lines of this to get you started:
public class Grid {
private var _content:Vector.<Vector.<Cell>>;
public function Grid(columns:int, rows:int) {
// Fill _content with empty slots based on columns, rows.
}
public function getCell(x:int, y:int):Cell {}
public function cellExists(x:int, y:int):Boolean {}
}

All elements change in Arraylist - Processing

My program is a zombie survival game, set in a 2d array of blocks.
I use an arraylist - my first attempt - to store the zombies, and each in tern "checks" if there is a block above, below and around it, to detect it's movement.
I'll post the relevant code here, and upload the sketch folder separately.
ArrayList zombies;
void setup() {
zombies = new ArrayList();
}
void draw() {
for (int i = 0; i < zombies.size(); i++) {
Zombie zombie = (Zombie) zombies.get(i);
zombie.draw();
}
}
void keyPressed() {
if (key == 'z') {
zombies.add(new Zombie());
}
}
class Zombie
{
int posX = 20;
int posY = 10;
boolean fall;
boolean playerOnBlock;
Zombie() {
posX = 10;
posY = 590;
fall = false;
}
void draw() {
grid.blockCheck(posX, posY, 2);
fill(0, 255, 0);
rect(posX, posY, 10, 10);
}
void fall() {
posY += 5;
println("zombiefall"+posY);
}
void move(boolean left, boolean right, boolean above) {
if (left == true && player.playerX < posX) {
posX -= 1;
}
if (right == true && player.playerX > posX) {
posX += 1;
}
}
}
class Grid {
void blockCheck(int x, int y, int e) {
for (int i = 0; i < l; i++)
for (int j = 0; j < h; j++)
{
grid[i][j].aroundMe (x, y, i, j, e);
}
}
}
class Block {
void aroundMe(int _x, int _y, int _i, int _j, int entity) {
int pGX = _x/10;
int pGY = _y/10;
if (entity == 1) {
if (pGY+1 == _j && pGX == _i && state == 4) {
player.fall();
}
if (pGX == _i && pGX-1 <= _i && _y == posY && state == 4) {
leftOfMe = true;
}
else
{
leftOfMe = false;
}
if (pGX+1 == _i && _y == posY && state == 4) {
rightOfMe = true;
}
else
{
rightOfMe = false;
}
if (pGY-1 == _j && _x == posX && state ==4) {
aboveOfMe = true;
}
else
{
aboveOfMe = false;
}
player.controls(leftOfMe, rightOfMe, aboveOfMe);
}
if (entity == 2) {
if (pGY+1 == _j && pGX == _i && state == 4) {
for (int i = 0; i < zombies.size(); i++) {
Zombie zombie = (Zombie) zombies.get(i);
zombie.fall();
}
}
if (pGX == _i && pGX-1 <= _i && _y == posY && state == 4) {
ZleftOfMe = true;
}
else
{
ZleftOfMe = false;
}
if (pGX+1 == _i && _y == posY && state == 4) {
ZrightOfMe = true;
}
else
{
ZrightOfMe = false;
}
if (pGY-1 == _j && _x == posX && state ==4) {
ZaboveOfMe = true;
}
else
{
ZaboveOfMe = false;
}
for (int i = 0; i < zombies.size(); i++) {
Zombie zombie = (Zombie) zombies.get(i);
zombie.move(ZleftOfMe, ZrightOfMe, ZaboveOfMe);
}
}
Sketch is here: http://www.mediafire.com/?u5v3117baym846v
I believe the problem lies in specifying which element of an arraylist I am referring to, as I can observe the issues to be:
All "zombies" fall when one detects that it should fall.
Zombie's speed increases with each additional zombie added - somehow treating all the zombie elements as one zombie object?
This might be a similar issue:
All elements of An ArrayList change when a new one is added?
But I've fiddled with my project and I can't seem to get it working still.
Please don't hesitate to ask for more information on my project. I will be with my computer all evening so should be able to reply quickly. Thanks in advance.
Thanks for your help.
I'm using it like this:
ArrayList <Zombie> zombies = new ArrayList <Zombie>();
-------------------------------------------
void setup(){
zombies = new ArrayList();
-------------------------------------------
void draw(){
for (Zombie z:zombies) {
z.draw();
}
}
-------------------------------------------
void keyPressed() {
if (key == 'z') {
for (int i = 0; i< 1; i++) {
zombies.add(new Zombie(i));
}
}
-------------------------------------------
class Zombie
{
int posX = 20;
int posY = 10;
boolean fall;
boolean playerOnBlock;
int z;
Zombie(int _z) {
posX = 10;
posY = 590;
fall = false;
z = _z;
}
void draw() {
grid.blockCheck(posX, posY, 2);
fill(0, 255, 0);
rect(posX, posY, 10, 10);
}
void fall() {
posY += 5;
println("zombiefall"+posY);
}
void move(boolean left, boolean right, boolean above) {
if (left == true && player.playerX < posX) {
posX -= 1;
}
if (right == true && player.playerX > posX) {
posX += 1;
}
}
}
Here is the idea :)
//use generics to keep it simple. Only Zoombies in this list
ArrayList <Zoombie> samp = new ArrayList <Zoombie>();
void setup() {
//a regular for loop to use the i as id
for (int i = 0; i< 100; i++) {
samp.add(new Zoombie(i));
}
//run just once
noLoop();
}
void draw() {
//a enhanced for, no need for use get()
// z will represent each element in the collection
for (Zoombie z:samp) {
z.d();
}
println("done");
}
// a dummy class ;)
class Zoombie {
int id;
Zoombie (int _id)
{
id =_id;
}
void d()
{
println(id);
}
}

TicTacToe Array. Winner method and is square free

I dont know what I'm doing wrong here.
Can anyone tell me what's wrong with my checkRow code in checkWinner and isSquareFree method?
Here's my code:
public class TicTacToe
{
/**
* intance variables to hold the data's state for the game.
*/
public static final int GRIDSIZE = 3;
public static final char BLANK = ' ';
public static final char TIE = 'T';
public static final char NOUGHT = 'O';
public static final char CROSS = 'X';
private char[][] grid;
private char WhoseTurn;
/**
* Construct a tic tac toe grid ready to play a new game.
* The game grid should be GRIDSIZE by GRIDSIZE spaces
* all containing the BLANK character.
* Initially, the starting player is not decided,
* indicated by setting whoseturn as BLANK.
*/
public TicTacToe()
{
this.WhoseTurn = BLANK;
this.grid = new char[GRIDSIZE][GRIDSIZE];
for (int r = 0; r < grid.length; r++)
{
for ( int c = 0; c < grid[r].length; c++)
{
this.grid[r][c] = BLANK;
}
}
}
/**
* Reset the tic tac toe game ready to play again.
* Conditions for play are the same as for the constructor.
*/
public void newGame()
{
char[][] boardToClear = getGrid();
final int sizeOfBoard = grid.length;
for ( int row = 0; row < grid.length; row++)
{
for ( int col = 0; col < grid.length; col++)
{
grid[row][col] = BLANK;
}
}
}
public char[][] getGrid()
{
int gridLen = grid.length;
char[][] gridCopy = new char[gridLen][];
for ( int r = 0; r < gridCopy.length; r++)
{
gridCopy[r] = new char[gridCopy.length];
for ( int c = 0; c < gridCopy.length; c++)
{
gridCopy[r][c] = grid[r][c];
}
}
return gridCopy;
}
public char getWhoseTurn()
{
return WhoseTurn;
}
/**
* printGrid() displays the current state of the game grid
* on the console for debugging.
* It uses the form feed character \u000C to clear the console before
* printing the current grid.
*/
private void printGrid()
{
System.out.print('\u000C'); // clear the console window
for (int x = 0; x < GRIDSIZE-1; x++) {
System.out.print(grid[x][0] + "|" +
grid[x][1] + "|" + grid[x][2]);
System.out.println("\n-----"); //
System.out.print(grid[GRIDSIZE-1][0] + "|" +
grid[GRIDSIZE-1][1] + "|" +
grid[GRIDSIZE-1][2]);
}
}
// Now print last row (with no bottom edge)
private boolean checkIfGridFull()
{
char[][] board = getGrid();
int size = grid.length;
for ( int row = 0; row < size; row++)
{
for ( int col = 0; col < board[row].length; col++)
{
if ( grid[row][col] == BLANK)
{
return false;
}
}
}
return true;
}
public boolean move(char player, int row, int col)
{
char[][] boardToPlay = getGrid();
int size = grid.length;
char x = player;
if ( (player == NOUGHT) || ( player == CROSS))
{
if ( (x == WhoseTurn) || (WhoseTurn == BLANK))
{
if ((checkIfGridFull() == false) && ( boardToPlay[row][col] == BLANK))
{
if( (row < size) && ( col < size))
{
boardToPlay[row][col] = player;
if ( player == CROSS)
{
WhoseTurn = NOUGHT;
}
if ( player == NOUGHT)
{
WhoseTurn = CROSS;
}
return true;
}
}
}
}
return false;
}
public boolean isSquareFree( int row, int col)
{
if ((grid[row][col] == BLANK))
{
return true;
}
return false
;
}
public char checkWinner()
{
int countNought;
int countCross ;
int size = grid.length;
for ( int row = 0; row < size; row++)
{
countNought = 0;
countCross = 0;
for ( int col = 0; col < size; col++)
{
if ( grid[row][col] == CROSS)
{
countCross++;
}
if ( grid[row][col] == NOUGHT)
{
countNought++;
}
if ( countNought == size)
{
return NOUGHT;
}
if ( countCross == size)
{
return CROSS;
}
}
}
return BLANK;
}
}
One good method for tracking down a bug in a project like this is to use print line statements. Try this: put a print line somewhere near where you think the problem is, and print out the values of some of the local variables. If you see values that you shouldn't then you know that your data has come into some trouble earlier on in the code. In that case, move the print lines further back in the flow and try again. Keep doing this until you notice values going from good to bad (or bad to good): at that point you have tracked down the code that contains the bug.
Once you've done this, you will usually have only a small function to think about, and it will be much easier to understand what you've done wrong. If you still can't find the problem, then post the code snippet here and someone will probably be able to help you.
checkWinner() is wrong you're not checking diagonals, just write the eights winning combinations

Resources