hello there I have great problem with my methods. I wrote these methods to draw a card but in line that I have unicode for card faces it wont work correctly. because of this issue that the require space for these unicode is more than a whitespace it print it wrong. Is there anybody know how can I deal with this Issue? please help me with this issue.
First method is for card face and second is for creating multiple card together.
public String[] card(){
String[] card = new String[9];
card[0] = ("┌───────────┐");
card[1] = ( getNumber() < 10 ? "│ " + getNumber() +
" │" : "│"+( getNumber() == 10 ? "10" : getNumber() == 11 ? " J" : getNumber() == 12 ? "
Q" : " K")+" │");
card[2] = ("│ │") ;
card[3] = ("│ │");
card[4] = ("│─────"+ getFace() + "─────│") ;
card[5] = ("│ │") ;
card[6] = ("│ │") ;
card[7] =(getNumber() < 10 ? "│ " + getNumber() +
" │" : "│ "+( getNumber() == 10 ? "10" : getNumber() == 11 ? "J " : getNumber() == 12 ?
"Q " : "K ")+"│");
card[8] = ("└───────────┘");
return (card);
}
public static String renderCard(List<String[]> cards) {
String[] lines = new String[9];
String output = "";
for (int i = 0; i < 9; i++) {
for (String[] array : cards) {
lines[i] = (lines[i]==null ? "" : lines[i]) + " " + array[i];
}
}
for(String line : lines){
output += (line + "\n");
}
return output;
}
Output:
Output
I try many ways and figure out that this problem is cause by IntelliJ IDEA pre installed font. to solve this problem must go to:
File -> Settings -> Editor -> General -> Font -> Font
by changing font from JetBrains Mono to Consolas this problem will be solve.
Something wrong with String Index when checking and deleting symbols. How can I improve it?
func romanToInt(_ s: String) -> Int {
let romanDigits = ["I" : 1,
"V" : 5,
"X" : 10,
"L" : 50,
"C" : 100,
"D" : 500,
"M" : 1000]
let romanSums = ["IV" : 4,
"IX" : 9,
"XL" : 40,
"XC" : 90,
"CD" : 400,
"CM" : 900]
var sum = 0
var str = s
var charIndex = str.startIndex
for index in str.indices {
if index != str.index(before: str.endIndex) {
charIndex = str.index(after: index)
} else {
charIndex = str.index(before: str.endIndex)
}
let chars = String(str[index]) + String(str[charIndex])
if romanSums[chars] != nil {
print(chars)
str.remove(at: charIndex)
sum += romanSums[chars]!
print(sum)
} else {
let char = String(str[index])
print(char)
sum += romanDigits[char]!
print(sum)
}
print(str)
}
return sum
}
let check = romanToInt("MCMXCIV")
CONSOLE LOG:
M
1000
MCMXCIV
CM
1900
MCXCIV
XC
1990
MCXIV
IV
1994
MCXI
Fatal error: Can't advance past endIndex
You are modifying the string you are iterating over, so your indices become invalid. Instead, you could add a skipChar boolean that says that you've already handled the next character and then skip that character by executing continue:
func romanToInt(_ s: String) -> Int {
let romanDigits = ["I" : 1,
"V" : 5,
"X" : 10,
"L" : 50,
"C" : 100,
"D" : 500,
"M" : 1000]
let romanSums = ["IV" : 4,
"IX" : 9,
"XL" : 40,
"XC" : 90,
"CD" : 400,
"CM" : 900]
var sum = 0
var str = s
var charIndex = str.startIndex
var skipChar = false
for index in str.indices {
if skipChar {
skipChar = false
continue
}
if index != str.index(before: str.endIndex) {
charIndex = str.index(after: index)
} else {
charIndex = str.index(before: str.endIndex)
}
let chars = String(str[index]) + String(str[charIndex])
if romanSums[chars] != nil {
print(chars)
skipChar = true
sum += romanSums[chars]!
print(sum)
} else {
let char = String(str[index])
print(char)
sum += romanDigits[char]!
print(sum)
}
print(str)
}
return sum
}
let check = romanToInt("MCMXCIV")
print(check)
1994
for index in str.indices {
...
str.remove(at: charIndex)
It is not valid to modify a string while you are iterating over it. str.indices is fetched one time here, and is no longer valid once you've modified the underlying string.
I'm sure there will be a lot of implementations of this because it's the kind of small, fun problem that attracts implementations. So why not? This just screams recursion to me.
let romanDigits: [Substring: Int] = ["I" : 1,
"V" : 5,
"X" : 10,
"L" : 50,
"C" : 100,
"D" : 500,
"M" : 1000]
let romanSums: [Substring: Int] = ["IV" : 4,
"IX" : 9,
"XL" : 40,
"XC" : 90,
"CD" : 400,
"CM" : 900]
func romanToInt<S: StringProtocol>(_ s: S) -> Int
where S.SubSequence == Substring {
if s.isEmpty { return 0 }
if let value = romanSums[s.prefix(2)] {
return value + romanToInt(s.dropFirst(2))
} else if let value = romanDigits[s.prefix(1)] {
return value + romanToInt(s.dropFirst(1))
} else {
fatalError("Invalid string")
}
}
let check = romanToInt("MCMXCIV")
Of course this doesn't really check for valid sequences, so it's kind of junk. "IIIIXXIII" is kind of gibberish, but it works. But it's in keeping with the original approach.
Use reduce to make it flow here:
func romanToInt(_ s: String) -> Int {
if s.isEmpty {return 0}
let romanDigits = ["I" : 1,
"V" : 5,
"X" : 10,
"L" : 50,
"C" : 100,
"D" : 500,
"M" : 1000]
let romanSums = ["IV" : 4,
"IX" : 9,
"XL" : 40,
"XC" : 90,
"CD" : 400,
"CM" : 900]
return s.dropFirst().reduce((s.first!, romanDigits["\(s.first!)"]!)){
return ( $1, //current char
$0.1 + //previous sum
(romanSums["\($0.0)\($1)"] //add double value
?? ((romanDigits["\($1)"]!). + romanDigits["\($0.0)"]!)) //or single value and add duplicated
- romanDigits["\($0.0)"]!) // minus duplicated
}.1
}
print(romanToInt("MCMXCIV")). //1994
You are mutating str inside the loop, its end index is going change, in this case it gets lower than its original value. You can fix your code by checking that you haven't exceeded the endIndex on each iteration by using a while loop :
var index = str.startIndex
while index < str.endIndex {
...
//Before the closing curly brace of the while loop
index = str.index(after: index)
}
I was trying to reproduce a crash reported by one my users with the same message Can't advance past endIndex but I was not able to do it. Your code helped me figure out that this error changed in later versions of swift.
Your same code would report cannot increment beyond endIndex with swift 4.x runtime libraries, and String index is out of bounds with 5.x. The exact version numbers for the changes I do not know. But I suspect it is 4.0.0 and 5.0.0.-
var a = 0
(... up to var z = 0)
let letterchoosedbyplayer:String = LetterChoosed.text!
"LetterChoosed" is a textbox. The player enter a letter in this textbox.
I store the value in the variable "letterchoosedbyplayer".
Then i want to check if the variable called 'letterchoosedbyplayer' (it must be a letter of the alphabet) is equal to 1.
How can i do that?
I want to do that :
if \(letterchoosedbyplayer) = 1 {
}
Last Edit : All my code
let letterchoosedbyplayer:String = LetterChoosed.text!
if Int(letterchoosedbyplayer) == 1 {
print("vous avez perdu")
}
else {
switch letterchoosedbyplayer {
case "a":
print("lettre \(letterchoosedbyplayer) choisie")
a = 1
case "b":
print("lettre \(letterchoosedbyplayer) choisie")
b = 1
default:
print("cas défaut")
}
}
\() is used to append any object in a string. I don't think you can use this for your need
Try
if let letterchoosedbyplayer = LetterChoosed.text where letterchoosedbyplayer == "1" {
}
You could include the "1" case in the switch statement:
let letterchoosedbyplayer = LetterChoosed.text
if let lettrechoisie = letterchoosedbyplayer where !lettrechoisie.isEmpty {
switch lettrechoisie {
case "1": print("vous avez perdu")
case "a":
print("lettre \(lettrechoisie) choisie")
a = 1
case "b":
print("lettre \(lettrechoisie) choisie")
b = 1
default:
print("cas défaut")
}
}
Note that Int(letterchoosedbyplayer)! == 1 and letterchoosedbyplayer == "1" is the same thing.
Edit:
For your purpose you might use a dictionary rather than more than 20 single variables
var letterDict : [String : Int] = ["a" : 0, "b" : 0, "c" : 0, ... "z" : 0]
You can set a variable to 1 for example
letterDict["f"] = 1
Then you can check
if let lettrechoisie = letterchoosedbyplayer where !lettrechoisie.isEmpty {
let value = letterDict[lettrechoisie]!
if value == 1 {
// do something
} else {
// do something else
}
}
That avoids also a huge switch statement.
Would like to add an additional text at the end of an existing text in an array-item. The code which I have till now looks like:
for var i = 0; i < arrMain.count; i++ {
if (arrMain[i] as NSString).containsString("#ID-001") {
println("OK")
// Add additional text (eg. "Test") at the end of #ID-001
}
}
Every tried combination overwrites me #ID-001...
Try:
var arrMain:[AnyObject] = ["#ID-001"]
for var i = 0; i < arrMain.count; i++ {
if (arrMain[i] as NSString).containsString("#ID-001") {
arrMain[i] = (arrMain[i] as String) + "Test"
}
}
Either do this with the for-loop you already have, e.g.
var x = [ "a", "b", "c" ]
for index in 0 ..< x.count
{
if x[index] == "b"
{
x[index] += "_hello"
}
}
or use Swift's map function:
let y = x.map({ value -> String in return value == "b" ? value + "_hello" : value })
Please note, that
The second example will make a copy of the array.
Your array needs to be a mutable array, e.g. let x = [ ... ] won't work.
Assuming I understand the question:
arrMain[i] = arrMain[i].stringByReplacingOccurrencesOfString("#ID-001", withString: "#ID-001Test")
I have a function that stores the coordinates and the name of that chunk, but the problem is that this function gets called everytime new chunks get generated, but the old ones keep being loaded if they are not far. So the result is that in the textfile, the function writes the chunks sometimes 2 times.
I don't want this to happen and have the function only write every chunk once.
The main problem is that I can't use StreamwWriter and StreamReader at the same time.
This is my code:
function saveLoadedChunk() {
var loadedChunks : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
var fileName = "C:/Reactor Games/chunks.txt";
var sw : System.IO.StreamWriter = new System.IO.StreamWriter(fileName, true);
for (var i = 0; i < loadedChunks.length ; i++) {
if(loadedChunks[i].name.Substring(0,5) == "Chunk" || loadedChunks[i].name.Substring(0,5) == "_TERR") {
if(loadedChunks[i].tag != "Player") {
var xco = loadedChunks[i].transform.position.x;
var yco = loadedChunks[i].transform.position.y;
var zco = loadedChunks[i].transform.position.z;
var stringToWrite = "Chunk (" + xco + ", " + yco + ", " + zco + ")";
sw.WriteLine(stringToWrite);
}
}
}
sw.Flush();
sw.Close();
}
Preamble
I mostly work with C#, so there could be some mistakes in syntax.
Solution
You can store all your chunks in memory set. Inside saveLoadedChunk you are going to update this set and then write it's contents to file:
var chunks: HashSet<Vector3> = new HashSet<Vector3>();
function saveLoadedChunk() {
var loadedChunks : GameObject[] = FindObjectsOfType(GameObject) as GameObject[];
for (var i = 0; i < loadedChunks.length ; i++)
if(loadedChunks[i].name.Substring(0,5) == "Chunk" || loadedChunks[i].name.Substring(0,5) == "_TERR")
if(loadedChunks[i].tag != "Player")
chunks.Add(loadedChunks[i].transform.position);
var fileName = "C:/Reactor Games/chunks.txt";
var sw : System.IO.StreamWriter = new System.IO.StreamWriter(fileName, false);
for (var chunk: Vector3 in chunks) {
var stringToWrite = "Chunk (" + chunk.x + ", " + chunk.y + ", " + chunk.z + ")";
sw.WriteLine(stringToWrite);
}
}
The drawback here is:
That you start with blank chunks set every time app is launched.
You store all the chunks' coords in memory. But I wouldn't say that this is drawback until you have really-really lot of chunks.
In order to solve first problem you need to fill chunks with corrds stored in C:/Reactor Games/chunks.txt once the app is started.