Connect-Four Game in Scala - scala

I have to make a connect-four game using scala. I have attached the code but everytime the game runs and gets to row 3 it just continues to change the second rows entry instead of going to the next row. Any help would be appreciated. I found this code on another thread on here and couldn't figure out how to get it to work:
// makes the board
val table = Array.fill(9,8)('-')
var i = 0;
while(i < 8){
table(8)(i) = (i+'0').toChar
i = i+1;
}
// prints starting board
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
//player 1 moves
def playerMove1(){
val move = readInt
var currentRow1 = 7
while (currentRow1 >= 0)
if (table(currentRow1)(move) != ('-')) {
currentRow1 = (currentRow1-1)
table(currentRow1)(move) = ('X')
return (player2)}
} else {
table(currentRow1)(move) = ('X')
return (player2)
}
}
//player 2 moves
def playerMove2(){
val move = readInt
var currentRow2 = 7
while (currentRow2 >= 0)
if (table(currentRow2)(move) != ('-')) {
currentRow2 = (currentRow2-1)
table(currentRow2)(move) = ('O')
return (player1)}
} else {
table(currentRow2)(move) = ('O')
return (player1)
}
}
//player 1
def player1(){
printBoard(table)
println("Player 1 it is your turn. Choose a column 0-7")
playerMove1()
}
//player 2
def player2(){
printBoard(table)
println("Player 2 it is your turn. Choose a column 0-7")
playerMove2()
}
for (turn <- 1 to 32){
player1
player2
}

I've tried to make your code readable and compiling and also tried to fix some logic.
However, I've never worked with Scala so this is just a first sketch where you might want to continue ...
Some functions can be merged and the currentRow needed a fix. See here:
object ConnectFour{
val table = Array.fill(9,8)('-')
val currentRow = Array.fill(8)(8)
def main(args: Array[String]) {
var i = 0;
while(i < 8) {
table(8)(i) = (i+'0').toChar
i = i+1;
}
player(1)
}
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
def player(playerNr : Int){
printBoard(table)
println("Player " + playerNr + " it is your turn. Choose a column 0-7")
var column = readAndVerifyInt
var nextUser = 1 : Int
var symbol = 'O' : Char
if(playerNr == 1) {
symbol = 'X'
nextUser = 2
}
var curR = currentRow(column)
while (curR >= 0) {
if (table(curR)(column) != ('-')) {
curR = curR-1
currentRow(column) = curR
}
table(curR)(column) = symbol
player(nextUser)
}
}
def readAndVerifyInt() : Int = {
var column = readInt
if (column >= 0 && column <= 7) {
return column
} else {
println(" > Please try again")
return readAndVerifyInt
}
}
}

Related

Continue in Scala for loops

How do i convert below Java code to scala and use continue in for loop, this program remove minimum number of extra closed parenthesis in a given string
input : lee(t(c)o)de)
output : leet(t(c)o)de
public String minRemoveToMakeValid(String s){
StringBuilder sb =new StringBuilder();
in open =0;
for (char c : s.toCharArray()){
if(c == '('){
open++
}
else if(c == ')'){
if(open == 0) continue;
open --;
}
sb.append(c)
}
return sb
}
https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/
import util.control.Breaks._
val searchMe = "peter piper picked a peck of pickled peppers"
var numPs = 0
for (i <- 0 until searchMe.length) {
breakable {
if (searchMe.charAt(i) != 'p') {
break // break out of the 'breakable', continue the outside loop
} else {
numPs += 1
}
}
}
println("Found " + numPs + " p's in the string.")
Try it: https://scastie.scala-lang.org/R9sr95WESLyiKamCHHUVdQ
Im able to get it worked using below code
def minRemoveToMakeValid(s: String): String = {
var open = 0
val sb = new StringBuilder
for (c <- s.toCharArray) {
breakable {
if (c == '(') open += 1
else if (c == ')') {
if (open == 0)break
open -= 1
}
sb.append(c)
}
}
var result = new StringBuilder()
for(i<-sb.length()-1 to 0 by -1)
{
breakable{
open-=1
if(sb.charAt(i) == '(' && open >0) break
result.append(sb.charAt(i))
}
}
result.reverse.toString()
}

Access ArrayList outside nested If else block in Scala

I have following code :-
var ArrayStop = new ArrayList[imeistoppage]()
val listings = rddStopCalculate.zipWithIndex().map(p => {
if (p._2 == 0) {
imei = p._1.imei
lat = p._1.latitude
long = p._1.longitude
gpsdt = p._1.gpsdt
} else if (p._2 > 0 && p._2 != lastindex) {
if (p._1.imei.equals(imei) && p._1.latitude == lat && p._1.longitude == long) {
flag += 1
newgpsdt = p._1.gpsdt
} else {
if (flag > 0) {
timeDiff = newgpsdt.getTime() - gpsdt.getTime()
if (timeDiff > 60000) {
ArrayStop.add(imeistoppage(p._1.imei, lat, long, timeDiff))
}
flag = 0
}
imei = p._1.imei
lat = p._1.latitude
long = p._1.longitude
gpsdt = p._1.gpsdt
}
} else {
if (p._1.imei.equals(imei) && p._1.latitude == lat && p._1.longitude == long) {
flag += 1
newgpsdt = p._1.gpsdt
}
if (flag > 0) {
timeDiff = newgpsdt.getTime() - gpsdt.getTime()
if (timeDiff > 60000) {
ArrayStop.add(imeistoppage(p._1.imei, lat, long, timeDiff))
}
flag = 0
}
}
ArrayStop
}).collect()
val returnList = listings(listings.length - 1)
val tempCollection = returnList.asScala
val tempRDD = sc.parallelize(tempCollection)
tempRDD.saveToCassandra("db", "table", SomeColumns("imei", "lat", "long", "duration"))
As we can see in above code I'm actually adding data to ArrayStop for specific IF condition only and I want this to be accessed outside this rdd loop but I was unable to do so So I created a variable "listings" to store data which is actually taking all the rows whereas I want only those entries which are added in ArrayStop. So what is the best way to bring any array outside nested If-else block. This is different from this issue
Scala spark, listbuffer is empty
Thanks,

Scala , java "for" in scala

I don't know how convert java "continue" to scala.
I can use marker from bool + break, but its bad idea
Google did not help :(
It's my first program in scala... yep.. it's horrible
sort java
def sort(in: Array[Int], a:Int, b:Int)
{
var i,j,mode;
double sr=0;
if (a>=b) return; // size =0
for (i=a; i<=b; i++) sr+=in[i];
sr=sr/(b-a+1);
for (i=a, j=b; i <= j;)
{
if (in[i]< sr) { i++; continue; } // left > continue
if (in[j]>=sr) { j--; continue; } // right, continue
int c = in[i]; in[i] = in[j]; in[j]=c;
i++,j--; // swap and continue
}
if (i==a) return;
sort(in,a,j); sort(in,i,b);
}
sort scala...
def SortMerger(in:List[Int], a:Int, b:Int):Unit = {
var i = 0;
var j = 0;
var mode = 0;
var sr = 0.0;
if(a>=b) return;
i=a
while(i<=b)
{
sr+=in.ElementOf(i);
i += 1
}
sr=sr/(b-a+1)
i=a
j=b
while(i<=j)
{
if(in.ElementOf(i)<sr) {
i += 1;
// where continue??? ><
}
}
return
}
Scala has no continue statement, but what you are trying to do can be done with a simple if/else structure.
while(i<=j)
{
if(in(i) < sr) {
i += 1
} else if (in(j) >= sr) {
j -= 1
} else {
int c = in(i)
in(i) = in(j)
in(j) = c
i += 1
j -= 1
}
}
Note that the type of in here should be Array, not List

How to claculate adjacent data with spark/scala

I hava a RDD,the RDD type is Tuple2(value,timestamp),value is 1 or 0 , timestamp is a sequential, and a variable limitTime=4. When I map the RDD, if the value is 1 the output value from current timestamp to (timestamp +limitTime) is 1 ,else current value is 0, I call it is period. But there is a special case,when the value is 1 and its timestamp is in period,then it is ignored, the current value of output is 0
input : (0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)
expected output :(0,0),(1,1),(1,3),(1,5),(0,7),(0,8),(0,10),(1,12),(1,14),(1,15)
special input2: (0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)
expected output2:(0,0),(1,1),(1,3),(1,5),(0,7),(1,8),(1,10),(1,12),(0,14),(0,15)
this is my try:
var limitTime=4
var startTime= -limitTime
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)),4)
val results=rdd.mapPartitions(parIter => {
var resultIter = new ArrayBuffer[Tuple2[Int,Int]]()
while (parIter.hasNext) {
val iter = parIter.next()
if(iter._1==1){
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append(iter)
}else{
resultIter.append(iter)
startTime=iter._2
}
}else{
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append((1,iter._2))
}else{
resultIter.append(iter)
}
}
}
resultIter.toIterator
})
results.collect().foreach(println)
it's so inefficient,how can I get the same result without array?
Following code should work for both of your cases.
var limitTime=3
var first = true
var previousValue = 0
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)), 4)
val tempResult = rdd.collect.map(pair => {
if(first){
first = false
previousValue = pair._1
(pair._1, pair._2)
}
else {
if ((pair._1 == 1 || previousValue == 1) && limitTime > 0) {
limitTime -= 1
previousValue = 1
(1, pair._2)
}
else {
if (limitTime == 0) limitTime = 3
previousValue = pair._1
(pair._1, pair._2)
}
}
})
tempResult.foreach(print)
If it doesn't please let me know

How to define count without using var

I have this simple function that return some Status:
def getStatus : String =
{
//...
}
And i want to wait until this return specific status but still count this number of calls before exit:
def wait =
{
var count = 0
while (getStatus != "smeStatus" && count < 10) {
// some code here
count++
}
}
How can i avoid of using var ?
You can use a recursive method that takes the count-so-far and returns it + 1:
def waitUntilDone(countSoFar: Int): Int = {
if (getStatus != "smeStatus" && countSoFar < 10) {
// some code here
waitUntilDone(countSoFar + 1)
} else {
countSoFar
}
}
// invoke it starting with 0:
val count = waitUntilDone(0)
def status = ""
def waiting: Unit = {
def check(count: Int): Unit = {
if(count < 10 && status != "smeStatus") {
// do something
check(count + 1)
}
}
check(0)
}