Different execution under Windows and Linux with Go - go

I created a very small game of number guessing in Go. The thing is, it executes differently under Windows and under Linux. By executing it on Ubuntu for example, everything works just fine. But when I try to start it under Windows, it compiles just fine but during execution when I enter something (for example 5) it prints me twice "Smaller than random num"or "Bigger than random num". I have no idea why it happens.
package main
import (
"fmt"
"math/rand"
"time"
)
func main () {
var number int //declaration
var tries int = 0
random_number := random(1, 9) //gets random number
for ; ;tries++ {
//fmt.Printf("Enter your prediction: ")
fmt.Scanf("%v",&number)
if number == random_number {
break;
} else if number<random_number{
fmt.Printf("Smaller than random num\n")
} else {
fmt.Printf("Bigger than random num\n")
}
}
fmt.Printf("You guessed correctly in %v tries",tries)
}
func random(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max - min) + min
}

Newlines are different in Linux and Windows, and thus your program behaves differently.
See this issue: https://github.com/golang/go/issues/5391
To fix this, you can replace your Scanf with this (note the "\n" at the end):
fmt.Scanf("%v\n",&number)

Related

Using 256 colors in Go

How Can I used 256 colors in terminal with Golang.
As Libraries like faith/color only have limited colors support.
This python library here
use some kind of default code and a color code to print colored text in terminal.
I try to use color code but instead of color it printing color code in go program but in python program it prints colored text.
How can I print color use color code as above library doing...
Do I need to initialize the terminal ? If yes How?
Thanks!
I am expecting 256 colors to print in terminal.
*go version: 1.18.7
Windows can be weird. In some cases you need to set the console mode. If you are using Windows, specify it as part of your question.
colors.go:
package main
import (
"fmt"
"strconv"
)
func main() {
setConsoleColors()
for i := 0; i < 16; i++ {
for j := 0; j < 16; j++ {
code := strconv.Itoa(i*16 + j)
color := "\u001b[38;5;" + code + "m"
fmt.Printf("%s %-4s", color, code)
}
fmt.Println()
}
fmt.Print("\u001b[0m")
}
colors_windows.go:
//go:build windows
package main
import "golang.org/x/sys/windows"
func setConsoleColors() error {
console := windows.Stdout
var consoleMode uint32
windows.GetConsoleMode(console, &consoleMode)
consoleMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
return windows.SetConsoleMode(console, consoleMode)
}
colors_other.go:
//go:build !windows
package main
func setConsoleColors() error {
return nil
}

Print multiple rows in parallel Golang

I am attempting to write a horse race simulator with multiple rows.
Each row will represent one horse location calculated by a goroutine.
For some reason the code, when run on the Go Playground, does not output the numbers randomly as happens on my machine.
package main
import (
"math/rand"
"os"
"strconv"
"time"
)
var counter = 0
func main() {
i := 1
horses := 9
for i <= horses {
go run(i)
i++
}
time.Sleep(5000 * time.Millisecond)
print("\ncounter: " + strconv.Itoa(counter))
print("\nEnd of main()")
}
func run(number int) {
var i = 1
var steps = 5
for i <= steps {
print("[" + strconv.Itoa(number) + "]")
rand.Seed(time.Now().UnixNano())
sleep := rand.Intn(10)
time.Sleep(time.Duration(sleep) * time.Millisecond)
i++
counter++
}
if i == steps {
println(strconv.Itoa(number) + " wins")
os.Exit(1)
}
}
Playground: https://play.golang.org/p/pycZ4EdH7SQ
My output unordered is:
[1][5][8][2][3][4][7][9][6][7][9][9][4][3]...
But my question is how would I go about to print the numbers like:
[1][1]
[2][2][2][2][2][2][2][2]
[3][3][3]
...
[N][N][N][N][N]
you may want to check out this stackoverflow answer which uses goterm to move the terminal cursor and allow you to overwrite part of it.
The idea is that once you get to the terminal bit you want to be "dynamic" (much like a videogame screen clear+redraw), you always reposition the cursor and "draw" your "horses" position.
Note that with this you will need to store their positions somewhere, to then "draw" their positions at each "frame".
With this exercise you are getting close to how video games work, and for this you may want to set up a goroutine with a given refresh rate to clear your terminal and render what you want.

How can I let a function randomly return either a true or a false in go

I want to have a function that I can call to get a random true or false on each call:
randBoolean() // true
randBoolean() // false
randBoolean() // false
randBoolean() // true
How can I return a random boolean?
You need some kind of random information, and based on its value, you can return true in half of its possible cases, and false in the other half of the cases.
A very simple example using rand.Float32() of the math/rand package:
func rand1() bool {
return rand.Float32() < 0.5
}
Don't forget to properly seed the math/rand package for it to be different on each app run using rand.Seed():
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(rand1())
}
This is mentioned in the package doc of math/rand:
Use the Seed function to initialize the default Source if different behavior is required for each run.
If you don't seed, the same pseudo-random information is returned on each application run.
Some variations:
func rand2() bool {
return rand.Int31()&0x01 == 0
}
func rand3() bool {
return rand.Intn(2) == 0
}
And an interesting solution without using the math/rand package. It uses the select statement:
func rand9() bool {
c := make(chan struct{})
close(c)
select {
case <-c:
return true
case <-c:
return false
}
}
Explanation:
The select statement chooses one random case from the ones that can proceed without blocking. Since receiving from a closed channel can proceed immediately, one of the 2 cases will be chosen randomly, returning either true or false. Note that however this is far from being perfectly random, as that is not a requirement of the select statement.
The channel can also be moved to a global variable, so no need to create one and close one in each call:
var c = make(chan struct{})
func init() {
close(c)
}
func rand9() bool {
select {
case <-c:
return true
case <-c:
return false
}
}
This function returns true if the random integer is even else it returns false:
func randBool() bool{
return rand.Int() % 2 == 0
}
The easiest way will be to create a random number and then take its modulus of 2. Then if it is 0 the return true and if it is 1 then return false.
Here's another one liner, requires no random number generation/seeding etc., fairly simple :
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Got random bool:", getRandBool())
}
func getRandBool() bool {
now := time.Now()
nowNano := now.Nanosecond()
fmt.Println(nowNano)
return now.UnixNano()%2 == 0
}
Edited after #icza's comments : time.Now() is supposed to return time with nanosecond accuracy, but on Windows 10 Pro 64-bit (and I tried with go 1.8 & it may be true with other Windows OS too) it always returns time with lesser precision (probably micro second), rounding off the result so that it'll end with xxxxx..00 and hence this function will return true always. I have modified the function so one can see the result also. Works fine on Linux & probably should on other Unix OS'es too. So either use this function only after testing or better don't use if you need to deploy on a Windows system. It's unfortunate and hard to believe this, but it's a reality, bad Windows implementation. Thanks #icza for pointing out.

Print string X number of times without using loops or conditions

I was asked this question and could not come up with a solution, hope to find it here.
We need a function that receives a number (X) and a string, it needs to print that string X number of times, without using any loops or if-else conditions.
It's more about a generic algorithm not a specific programming language.
My initial response was recursion, but it requires an IF clause.
func (int x, string namme)
{
if(x>0)
{
print (name);
func(x-1);
}
}
In general case, you cannot do that. Even recursion's terminal case requires condition. The only solution in such case is ... Template magic (surprise!)
Here is the solution:
template <int times>
void print(const string& str);
template <>
void print<0>(const string& str)
{
}
template <int times>
void print(const string& str)
{
cout << str << " ";
print<times - 1>(str);
}
Such approach requres from you compile time value of number of times. But result code will not contain any conditions (you can see asm code)
Example of usage:
print<5>("Yeah!");
You can use a little trick in c++:
ยง4.7/4 (Integral Conversion)
If the source type is bool, the value false is converted to zero and the value true is converted to one.
This means you can index an array using a boolean value. If your array contains function pointers you implemented an if/else statement.
void noop(int,std::string) {}
void print_n_times(int times, std::string text) {
void (*next_function[])(int,std::string) = {
noop,
print_n_times
};
next_function[(times-1)>0](times-1, text);
std::cout << times << ' ' << text << '\n';
}
See it live
You can do the same thing in python:
Python 2.7.12 (default, Oct 10 2016, 12:56:26)
[GCC 5.4.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def noop(times,text):
... pass
...
>>> def print_n_times(times,text):
... next_function = [noop, print_n_times]
... print(text);
... next_function[int((times-1)>0)](times-1, text)
...
>>> print_n_times(4, "Hello World!")
Hello World!
Hello World!
Hello World!
Hello World!
Here is a complete program demonstrating this. I would not recommend writing anything like this in Real Life.
This takes advantage of the fact that subtracting 1 from 0 will set the most significant bit in an integer. I shift bit 63 down to 0 to get either a 1 or 0 (i.e. to avoid a conditional) and call one of two functions. runtime.Goexit will terminate a goroutine, but will call all deferred functions in the process. This unlocks a mutex that lets the sillyString function terminate only after all of the prints have happened.
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
sillyString("omg", 10)
}
func sillyString(s string, n int) {
var m sync.Mutex
m.Lock()
go func() {
defer m.Unlock()
mustGoDeeper(s, uint64(n-1), []func(){runtime.Goexit, func() {}})
}()
m.Lock()
}
func mustGoDeeper(s string, n uint64, fs []func()) {
sig := (1 - int(n>>63))
fs[sig]()
fmt.Printf("%s\n", s)
mustGoDeeper(s, n-1, fs)
}
Recursion looks like a good way to go, but we need to stop an infinite recursion. That means being sneaky. Using a try ... catch can do the job, at least in a language which supports that construct:
void printXtimes(String text, int x) {
try {
int z = 100 / x;
} catch (Exception ex) {
// Zero divide so exit program.
exit(0);
}
println(text);
printXtimes(text, x-1);
} // end printXtimes()
That is a Java-like pseudocode. In real Java the compiler gives a warning about infinite recursion, but it compiles and runs correctly, printing the text message the given number of times. An interesting problem.

Go MinGW compiler complains about if-else statement

Consider the following (useless) Go function:
func domagic(n int) int {
if n > 10 {
return n;
} else {
return 0;
}
}
This gives me the following compiler error:
main.go:15: function ends without a return statement
However, if i return a value outside the if-else block (before the end of the function), it compiles without errors.
Is this behavior by design, or is it something simply not yet implemented in the Go MinGW compiler?
Simple googling for the exact compiler error message yields this bugtracker issue. So I'd not say it's "by design" as it looks more like "it'd just happened to be implemented this way". See also this thread.
It's by design. Write:
package main
import "fmt"
func domagic(n int) int {
if n > 10 {
return n
}
return 0
}
func main() {
fmt.Println(domagic(7), domagic(42))
}
Output:
0 42

Resources