How to program the Sudoku game logic in Unity3D [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am trying to make a Sudoku game in Unity3D but I'm currently stuck on the logic behind the game. (checking if all the numbers in the same subgrid, row and column are different)
I have been able to get a script that generates the whole grid running, both for a 2x2, 2x3 and a 3x3 level. The part that I am stuck on is making the 2D Array to hold the selected values for all subgrids. I can also provide the full GenerateGrid script if it's needed, but any help apart from that would be of help.
(Note: I have tried my best to research as much as I can about this, but none of the stuff I found online was about a Unity3D version of the game, only 2D ones)
Thanks!

Something like this? The board is a 9x9 grid. Skip the multidimensional syntax as it just complicates things (in my opinion).
(Pseudocode - I haven't tried compiling this.)
int[] board = new int[9*9];
/// note that coordinates are zero-based. So, rows, columns. etc. go from 0..8, not 1..9
int getCell(int x, int y)
{
return board[y * 9 + x];
}
bool colIsValid(int x)
{
var digitsFound = new bool[9];
for(int y=0; y < 9; ++y)
{
var cellValue = getCell(x,y);
if (cellValue > 0)
{
if (digitsFound[cellValue])
return false;
digits[cellValue] = true;
}
}
return true;
}
bool rowIsValid(int y)
{
var digitsFound = new bool[9];
for(int x=0; x < 9; ++x)
{
var cellValue = getCell(x,y);
if (cellValue > 0)
{
if (digitsFound[cellValue])
return false;
digits[cellValue] = true;
}
}
return true;
}
// determine if the 3x3 subgrid containing cell (x,y) is valid.
bool subGridIsValid(int cellX, int cellY)
{
var minX = (cellX / 3) * 3;
var maxX = minX + 3;
var minY = (cellY / 3) * 3;
var maxY = minY + 3;
var digitsFound = new bool[9];
for(var j=minY; j < maxY; ++j)
{
for(var i = minX; i < maxX; ++i)
{
var cellValue = getCell(i,j);
if (cellValue > 0)
{
if (digitsFound[cellValue])
return false;
digitsFound[cellValue] = true;
}
}
}
return true;
}

You can represent yourself a Sudoku as a grid (with rows and columns). Each grid cell is itself a subgrid (with sub-rows and sub-columns)
To check if the user solved the Sudoku you have 3 conditions
there is no duplicate number in a subgrid itself
there is no duplicate number in a same sub-row for every cell on the same row
there is no duplicate number in a same sub-column for every cell on the same column
From there we can begin to work. I would recommend to use two sets of bidimensionnal arrays. One for the main grid and a second for each sub-grids
So basically...your grid declaration may looks like this int[,][,] sudoku and sudoku[1,2][3,4] will access the row 1, column 2, sub-row 3, sub-column 4 if that makes sense
So to check game conditions:
test every sub-cells of sudoku[1,2][i,j] to make sure there is no duplicated numbers in the grid cell [1,2]
test every sub-cells for sudoku[1,i][2,j] to make sure there is no duplicated number in the sub-column 2 of the column 1
test every sub-cells for sudoku[i,1][j,2] to make sure there is no duplicated number in the sub-row 2 of the row 1
You should find a better optimisation to check the grid rather than brute force it sub-cell by sub-cell but I leave it up to you.
Hope that helped ;)

Related

How can i fill a square with randomly sized squares and rectangles

So i need to know how i can go about filling an area with randomly sized rectangles and squares - like this for instance:
I already have a partially working demo however it has alot of instances in where it will not work and ontop of this it requires alot of manual checks which isn't the easiest thing to program nor is it efficient.
Ontop of the challenge at hand i'd like to also avoid using methods that require checking collision such as using an attached RigidBody2D or a Ray cast as i'm working with ui and would like to simply generate a table of locations and sizes for easier access (however if this is unavoidable i understand and please do still share your answer if this is the case)
I was hoping to simulate it in the sense of a table where you can merge cells together but i'm uncertain how this is achievable - if at all.
Thankyou in advance! :)
Edit:
In relation to UnholySheep's comment i found this. The Kd-Tree looks promising but (correct me if i'm wrong) i don't believe it can be immplemented in csharp without programming out of scope and i think it literally draws squares as opposed to implements gameobjects or Rect objects with a size and position.
Furthermore there's this thread but again it mentions using a Kd-Tree or methods which i want to avoid or as Brian said using a merge method which i don't think is achieavable in unity without programming an entire table module which is out of scope again. Additionally someone mentioned using a spiral which albeit is an interesting approach it wouldn't result in the randomness i want to achieve.
To clarify i am looking for a fairly simple algorithm - i don't believe a Kd-tree fits this but for anyone else this may be an option as there are unity modules for this.
Your question is a challange, plus writing code that perfectly produces the image takes a lot of time and patience. But here I wrote code that puts a field of all kinds of letters in a 2D array. As long as this array is empty it will allow itself to fill them with random rectangles.
public enum squareType { none, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, Y, W, X, Z }
public squareType[,] cases = new squareType[4,4];
public void Start()
{
var lengthX = cases.GetLength(0);
var lengthY = cases.GetLength(1);
var index = 0;
for (var i = 0; i < lengthX; i++)
{
for (var j = 0; j < lengthY; j++)
{
if (cases[i,j] != squareType.none) continue;
var randomX = Random.Range(i, Mathf.Min(i+3, lengthX));
var randomY = Random.Range(j, Mathf.Min(j+3, lengthY));
var color = (squareType) Enum.ToObject(typeof(squareType), ++index);
for (var x = i; x <= randomX; x++)
{
for (var y = j; y <= randomY; y++) cases[x, y] = color;
}
}
}
// Debug table
for (var i = 0; i < lengthX; i++)
{
var xField = "";
for (var j = 0; j < lengthY; j++) xField += " | " + cases[i, j];
Debug.Log(xField);
}
}
Example Result 4x4:
Example Result 6x6:

It says I need to add "," in C#, Where do I put it? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I tried to make a FizzBuzz code in C# but the error code it gives me is that I'm missing a " , " somewhere but I can't find where to place it
Also I know there are other underlying programs in the code I just need this fixed so I can compile and fix them
using System;
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
float i = 0;
if (i != 101)
{
i = i + 1;
float i3 = i / 3;
float i5 = i / 5;
float i15 = i / 15;
string Print = Convert.ToString(i)
else ; if ((i3 %1) > 0)
{
string Hold = ("Fizz");
Print = Hold;
}
else if ((i3 % 1) > 0)
{
string Hold = ("Buzz");
Print = Hold;
}
else if ((i15 % 1) > 0)
{
string Hold = ("FizzBuzz");
Print = Hold;
}
Console.WriteLine(Print)
; Console.WriteLine("Done");
Console.ReadLine();
}
}
}
}
Fizz-Buzz was originally a game designed to teach children division, it worked like this:
The player designated to go first says the number "1", and each player counts one number in turn. However, any number divisible by three is replaced by the word fizz and any divisible by five by the word buzz. Numbers divisible by both become fizz buzz.
So your program has a number of errors, first one is that you use an if where you should be looping. Your first if statement:
if (i != 101)
{ ... }
Really doesn't do anything. You set i=0 in the previous statement, so i will never equal 101. What you need to do instead is a while loop:
float i = 0.0f;
while (i < 101.0f)
{
//Run the program
}
The next problem you have is that it is OK to use i for an iterator, or even x or y if iterating dimensions, but that is really where the single letter variables should stop. Use meaningful names, it makes things much easier:
So, again we need to check if i is divisible by 3, 5, or both. We can do that with simple boolean variables, no need to make things more complicated.
bool divisibleBy3 = i % 3.0f == 0.0f;
bool divisibleBy5 = i % 5.0f == 0.0f;
The next thing you have wrong is that you have ; in strange places, namely you seem to mix them in on separate lines. Try not to do this. There are very few reasons that a ; should not be on the end of every code line, and there should really only be one per line. So this:
string Print = Convert.ToString(i)
else ; if ((i3 %1) > 0)
Is an error because it treats it all as one line until it hits the ;, so your code really becomes:
string Print = Convert.ToString(i) else;
if (...)
And it should be obvious what the problem with that is.
The last problem I'll touch on really isn't a code issue, but a form one. You have a lot of "holding" variables that don't do anything but temporarily put things in places then put them somewhere else, like this:
if ((i3 %1) > 0)
{
string Hold = ("Fizz");
Print = Hold;
}
What is the purpose of Hold? You could just write:
Print = "Fizz";
The ( and ) are also unnecessary. So lets take all these lessons and put them into the Fizz-Buzz program:
int i = 0; //No reason to use float here, int is just fine
while (i <= 100)
{
bool divisibleBy3 = i % 3 == 0;
bool divisibleBy5 = i % 5 == 0;
if (divisibleBy3 && divisibleBy5)
Console.WriteLine("FizzBuzz");
else if (divisibleBy3)
Console.WriteLine("Fizz");
else if (divisibleBy5)
Console.WriteLine("Buzz");
else
Console.WriteLine(i.ToString());
i += 1;
}
Console.WriteLine("Done");
Console.ReadKey(true);
Or, it can be written with a for loop:
for (int i = 0; i <= 100; i++)
{
bool divisibleBy3 = i % 3 == 0;
bool divisibleBy5 = i % 5 == 0;
if (divisibleBy3 && divisibleBy5)
Console.WriteLine("FizzBuzz");
else if (divisibleBy3)
Console.WriteLine("Fizz");
else if (divisibleBy5)
Console.WriteLine("Buzz");
else
Console.WriteLine(i.ToString());
}
Console.WriteLine("Done");
Console.ReadKey(true);
So you can see how giving variables meaningful names, paying attention to indenting/formatting, and understanding of the ; can help you make debugging easier. Clean, well formatted code is easy to read and debug, and giving variables meaningful names means you can tell what the purpose is without having to read through the entire use of the variable.
Note: Some programmers will argue that Fizz-Buzz can be condensed down to 1-3 lines of code. While it is possible, I would argue that it doesn't demonstrate good programming practices. There is a big difference between readable code that can be maintained, and just making something short for the sake of it being short.

2D Array IndexOutOfRange Issue in Unity C# [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have 35 Tile objects and I'm trying to put them into a 2D array (and list) but I keep getting an IndexOutofRange error when populating the array. The code I'm using is:
private Tile[,] AllTiles = new Tile[5,7];
private List<Tile> EmptyTiles = new List<Tile>();
// Use this for initialization
void Start () {
Tile[] AllTilesOneDim = GameObject.FindObjectsOfType<Tile> ();
foreach (Tile t in AllTilesOneDim) {
// Fill 2D Array AllTiles
AllTiles [t.indRow, t.indCol] = t;
// Fill List with all tiles
EmptyTiles.Add (t);
}
}
I should note that each Tile object contains an int for indRow between 0-4 and an int for indCol between 0-6.
Try adding some defensive code to check the range before adding the tile to the 2D array. Like:
int rows = AllTiles.GetLength(0);
int cols = AllTiles.GetLength(1);
int indRow = 0;
int indCol = 0;
foreach (Tile t in AllTilesOneDim) {
indRow = t.indRow;
indCol = t.indCol;
if (indRow >= 0 && indRow < rows
&& indCol >= 0 && indCol < cols)
{
// Fill 2D Array AllTiles
AllTiles[indRow, indCol] = t;
}
}
Use the debugger to step into this path and see what you find. The indRow and indCol values must sometimes be outside of your specified ranges of 5 (0 to 4) and 7 (0 to 6). Remember indexes are zero based and the Length returns the total number of items so we must subtract one to find the correct index (or use "index less than rows or cols" like I did in the if statement).
GetLength() Method:
https://msdn.microsoft.com/en-us/library/system.array.getlength.aspx
https://stackoverflow.com/a/4260228/8094831

Procedure to separate branch of data in to few set by using for loops in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
First of all, i stored 90 data in a list.
After that I want to separate those data to 30 data each set, which means that I have 3 set of data that consist 30 data each.
By using the code below, I get what I want but i don't really understand how's it works.
for (int i = 0; i < 3; i++)
{
for (int j = 0 + (i * 30); j < 30 + (i * 30); j++)
{
}
}
For what I understand is the first loop split the data in to 3 set and the second loops is for 30 data for each set.
Let's say if i have 1000 data now and i want to make it to 100 data each set , so i have 10 set data in total.
So,
for (int i = 0; i < 10; i++)
{
for (int j = 0 + (i * 100); j < 100 + (i * 100); j++)
{
}
}
Why do for (int i = 0; i < 10; i++) / for (int i = 0; i < 3; i++) come first instead of the second loops?
Is it that every time if I want to separate a brunch of data to a few set, the first loops
that i have to declare is how many set i want to data to be???
sometimes, it's better to refactor and have explaining variables ( or functions)
Also, added Console Output to help show what it's doing
int sets = 3;
int setSize = 30;
for (int i = 0; i < sets; i++)
{
Console.Write($"Set {i} : ");
int from = i * setSize;
for (int j = from; j < from + setSize; j++)
{
Console.Write($" {j}");
}
Console.WriteLine();
}
Is it that every time if I want to separate a brunch of data to a few set, the first loops that i have to declare is how many set i want to data to be???
Yes, it's the convenient way to do that,
This may show a more clear idea of this:
for (int i = 0; i < 3; i++)
{
// i is the page
for (int j = 30*(i); j < 30*(i+1); j++)
{
// 30 is the step and j is the offset
}
}
Sometimes This structure is called pagination
which the first loop defines the page and second inner loop defines the step and together they calculate the offset
Technically you can write your program any way you like, as long as it works.But remember, others may need to read your code (for example you left the company and others have taken up your post), and you code in a way that only YOU can understand, thats not a well written code.
There are two main criteria:
Readability: How easy is the code to read?
Writeability:How easy is the code to write?
Balancing the two criteria makes a better coding style.
In your case, breaking it into two for loops (first one indicates the number of sets, second one indicates number of entries) makes perfect sense and is easy to understand.

I'm trying to do a Prime Number finder but cant see why it's not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to do a Prime Number finder but cant see why it's not working.
When i run the debug test nothing show in the console. Could someone check it and tell me what i do wrong?
List<int> primes = new List<int>();
primes.Add(2);
primes.Add(3);
int maxPrime = 11; //The maximum found Primes
int primeCount = primes.Count; //Current Number of Primes
int num = 4; //Current Number
int x = 0; //
int curPrime = primes[x];
while (primeCount < maxPrime)
{
if (x != primeCount)
{
if (num % primes[x] == 0)
{
num++;
x = 0;
}
else
{
x++;
}
}
else
{
primes.Add(num);
primeCount=primes.Count;
x = 0;
}
}
primes.ForEach(i => Console.Write("{0}\t", i));
You have an infinite loop.
Since you never modify primeCount or maxPrime, this will always be true:
while (primeCount < maxPrime)
In order to end that loop, you need to modify one of those two values in such a way that the condition will evaluate to false.
(Note: There appear to also be other bugs/problems in the code aside from this. For example, num = num++; doesn't do what you probably think it does.)

Categories

Resources