C# Instantiate Vector3 Problems - c#

I'm a beginner of learning programming
Instantiate(o, new Vector3(LocateX, LocateY, 0), transform.rotation);
In this code Visual Studio 2022 keeps telling me there is an error with LocateX and LocateY...
Please help me
using Unity
error code : CS0165
FixedCode
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class OXScript : MonoBehaviour
{
private int clickNumber;
public GameObject o;
public int spotNumber;
// Start is called before the first frame update
void Start()
{
clickNumber= 0;
}
// Update is called once per frame
void Update()
{
}
public void SpawnO()
{
// 1, 2, 3, y = 3
// 4, 5, 6, y = 0
// 7, 8, 9, y = -3
// x=-3 x=0 x=3
float LocateX = 0;
float LocateY = 0;
int ix = 0;
for(int i=1; i<10; i++)
{
if (clickNumber == 0 && spotNumber == i)
{
// y
if(1 <= i && i <= 3 )
{
LocateY = 3;
} else if(4 <= i && i <= 6)
{
LocateY = 0;
} else if (7 <= i && i <= 9)
{
LocateY = -3;
}
//x
if (ix == (i - 1) % 3)
{
LocateX = -3;
} else if (ix + 1 == (i - 1) % 3)
{
LocateX = 0;
} else if (ix + 2 == (i - 1) % 3)
{
LocateX = 3;
}
Instantiate(o, new Vector3(LocateX, LocateY, 0), transform.rotation);
spotNumber ++;
clickNumber ++;
}
}
}
}
Problem Solved!!
I know my code is not clean at all so thank you for helping noob everyone!

Initialization is required before using local variables.
float LocateX = 0;
float LocateY = 0;

You can try using modulo arithemtics here: for
1, 2, 3 y = 3
4, 5, 6 y = 0
7, 8, 9 y = -3
x = -3 x = 0 x = 3
we can put
x = ((i - 1) % 3 - 1) * 3
y = (1 - (i - 1) / 3) * 3
And get
public void SpawnO() {
for (int i = 1; i < 10; ++i) {
if (clickNumber == 0 && spotNumber == i) {
int LocateX = ((i - 1) % 3 - 1) * 3
int LocateY = (1 - (i - 1) / 3) * 3;
Instantiate(o, new Vector3(LocateX, LocateY, 0), transform.rotation);
spotNumber += 1;
}
}
}

Related

Using Stopwatch in C#

Does anyone know how I can add a timer function to this code that solves sudoku puzzles?
I've tried the Stopwatch class but I can't get it to work because I don't know exactly where to put it. I've tried several places but always get errors. The main purpose of the code works but I'd like to add a timer function to see how long the code ran for.
using System;
namespace SuDoKu
{
public class SuDoKu
{
private int[,] grid;
public SuDoKu()
{
grid = new int[9, 9];
}
static void Main(string[] args)
{
SuDoKu sdk = new SuDoKu();
int[,] grd = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
sdk.EnterToGrid(grd[i, j], new Point(i, j));
Console.WriteLine("Original Grid");
sdk.Display();
sdk.Solve(sdk.NextAvailableCell(), new Point());
Console.WriteLine("\n\n\nSolved Grid");
sdk.Display();
Console.WriteLine();
}
public void Display()
{
for(int i = 0; i < 9; i++)
{
Console.WriteLine();
for(int j = 0; j < 9; j++)
{
if(ShowFromGrid(new Point(i, j)) == 0) {
Console.Write("0 ");
}
else
{
Console.Write(ShowFromGrid(new Point(i, j)) + " ");
}
if(j == 2 || j == 5)
{
Console.Write("| ");
}
}
if(i == 2 || i == 5) {
Console.Write("\n------|-------|------ ");
}
}
}
public void EnterToGrid(int num, Point pos) {
grid[pos.X, pos.Y] = num;
}
public int ShowFromGrid(Point pos) {
return grid[pos.X, pos.Y];
}
public void Solve(Point pos, Point prevPos) {
if(pos.X < 9 && pos.Y < 9)
{
Point posPrev = new Point();
if(grid[pos.X, pos.Y] == 0)
{
for(int i = 1; i <= 9; i++)
{
if(IsThisNumberPossibleInTheGrid(i, pos))
{
grid[pos.X, pos.Y] = i;
posPrev.X = pos.X;
posPrev.Y = pos.Y;
Point posNext = NextAvailableCell();
if(!posNext.Equals(new Point()))
Solve(posNext, posPrev);
}
}
if(grid[pos.X, pos.Y] == 0)
{
if(!prevPos.Equals(new Point()))
grid[prevPos.X, prevPos.Y] = 0;
return;
}
}
}
else
{
Point posNext = NextAvailableCell();
if(!posNext.Equals(new Point()))
Solve(posNext, pos);
}
}
public Point NextAvailableCell()
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
if(grid[i, j] == 0)
return new Point(i, j);
return new Point();
}
public bool IsThisNumberPossibleInTheGrid(int num, Point pos) {
if(IsThisNumberPossibleInTheBlock(num, pos))
{
for(int i = 0; i < 9; i++)
{
if(grid[i, pos.Y] == num && pos.X != i)
{
return false;
}
if(grid[pos.X, i] == num && pos.Y != i)
{
return false;
}
}
return true;
}
return false;
}
public bool IsThisNumberPossibleInTheBlock(int num, Point pos)
{
Point Grid = new Point();
Grid.X = (pos.X >= 0 && pos.X <= 2) ? 0 : ((pos.X >= 3 && pos.X <= 5) ? 3 : ((pos.X >= 6 && pos.X <= 8) ? 6 : -1));
Grid.Y = (pos.Y >= 0 && pos.Y <= 2) ? 0 : ((pos.Y >= 3 && pos.Y <= 5) ? 3 : ((pos.Y >= 6 && pos.Y <= 8) ? 6 : -1));
if(!Grid.Equals(new Point()))
{
for(int i = Grid.X; i < Grid.X + 3; i++)
{
for(int j = Grid.Y; j < Grid.Y + 3; j++)
{
if(grid[i, j] == num && !pos.Equals(new Point(i, j)))
return false;
}
}
return true;
}
return false;
}
}
public class Point
{
public int X;
public int Y;
public Point()
{
this.X = -1;
this.Y = -1;
}
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
public bool Equals(Point p)
{
return (this.X == p.X && this.Y == p.Y) ? true : false;
}
}
}
The Stopwatch object is often used to (as you do here), measure how long things take. One quick thing to remember here is that it will take the time for everything you do between starting and stopping it, so make sure you only put the actual code you want to time between those.
using System.Diagnostics;
//...
void StopwatchUsingMethod()
{
//A: Setup and stuff you don't want timed
var timer = new Stopwatch();
timer.Start();
//B: Run stuff you want timed
timer.Stop();
TimeSpan timeTaken = timer.Elapsed;
string foo = "Time taken: " + timeTaken.ToString(#"m\:ss\.fff");
}
Foo will here show the minutes, seconds, and milliseconds it took to complete, though will show as wrong if it takes more than 59 minutes. Further information about TimeSpan can be found here: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings
If I understand your code correctly, you want to put everything up to and including the first sdk.Display(); line in the A section and only put the call to Solve in the B section, so something like
static void Main(string[] args)
{
//...
sdk.Display();
var timer = new Stopwatch();
timer.Start();
sdk.Solve(sdk.NextAvailableCell(), new Point());
timer.Stop();
Console.WriteLine("\n\n\nSolved Grid");
//...you can use the time taken here
}
In .NET 7.0 there were some improvements in the Stopwatch class. There is a better way to use Stopwatch that will be more accurate, slightly faster, and won't use memory allocation at all!
You should use the methods Stopwatch.GetTimeStamp() & Stopwatch.GetElapsedTime(long) to make the improvements.
An example would be:
long startTime = Stopwatch.GetTimestamp();
// Do Something...
TimeSpan elapsedTime = Stopwatch.GetElapsedTime(startTime);
For more info, read the Stopwatch in .NET 7.0 documentation.
"The main purpose of the code works but I'd like to add a timer function to see how long the code ran for"
For this you can use System.Diagnostics.Stopwatch(https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.7.2).
If you want to see how long a function takes to execute, add stopWatch.Start() before and stopWatch.Stop() after the function calls. You can now see total time it took(in seconds/milliseconds etc) using stopWatch.Elapsed, according to your convenience.

How to process an array correctly

Here's the part 1 of my question, if you wanna check the background of this question :
Detecting brackets in input string
Forgive me if the title doesn't match, since I also confused how to name it appropriately to picture my problem. If anyone knows a more appropriate title, feel free to edit.
So, given below code (my own code) :
private const int PARTICLE_EACH_CHAR = 4;
/*ProcessBarLines : string s only contains numbers, b, [, and ]*/
private int ProcessBarLines(Canvas canvas, string s, int lastLineAboveNotation)
{
List<int> bracket = new List<int>();
List<int> other = new List<int>();
int currentCloseNumber = 0;
int currentOpenNumber = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '[')
{
bracket.Add(i);
currentOpenNumber++;
if (i - 1 > 0 && s[i - 1] != '[')
{
currentOpenNumber = 1;
}
}
else if (s[i] == ']')
{
bracket.Add(i);
currentCloseNumber++;
if (i + 1 >= s.Length || s[i + 1] != ']' || currentOpenNumber == currentCloseNumber)
{
int min = bracket.Count - (currentCloseNumber * 2);
int max = bracket[bracket.Count - 1];
List<int> proc = new List<int>();
int firstIndex = -1;
int lastIndex = -1;
for (int ii = 0; ii < other.Count; ii++)
{
if (other[ii] > min && other[ii] < max)
{
proc.Add(other[ii]);
if (firstIndex == -1)
{
firstIndex = ii;
lastIndex = ii;
}
else
{
lastIndex = ii;
}
}
}
double leftPixel = firstIndex * widthEachChar;
double rightPixel = (lastIndex * widthEachChar) + widthEachChar;
DrawLine(canvas, currentCloseNumber, leftPixel,
rightPixel, lastLineAboveNotation * heightEachChar / PARTICLE_EACH_CHAR);
lastLineAboveNotation += currentCloseNumber - 1;
currentOpenNumber -= currentCloseNumber;
currentCloseNumber = 0;
}
}
else
{
other.Add(i);
}
}
return lastLineAboveNotation + 1;
}
Here's the test cases :
Picture 1 & 2 is the correct answer, and picture 3 is the wrong answer. Picture 3 should have a line, just like inverted from number 2, but, apparently, (if you look closely) the line is drawn on the right, but it should be on the left to be correct (above 0).
I figured, the problem is, I'm quite sure on the "min". Since it doesn't give the correct starting value.
Any idea on this? Feel free to clarify anything. It's used for writing numeric musical scores.
Btw, DrawLine() just meant to draw the line above the numbers, it's not the problem.
Finally! I found it!
private int ProcessBarLines(Canvas canvas, string s, int lastLineAboveNotation)
{
List<int> bracket = new List<int>();
List<int> other = new List<int>();
int currentCloseNumber = 0;
int currentOpenNumber = 0;
int space = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '[')
{
bracket.Add(i);
currentOpenNumber++;
if (i - 1 > 0 && s[i - 1] != '[')
{
currentOpenNumber = 1;
}
}
else if (s[i] == ']')
{
bracket.Add(i);
currentCloseNumber++;
if (i + 1 >= s.Length || s[i + 1] != ']' || currentOpenNumber == currentCloseNumber)
{
int min = bracket[Math.Max(bracket.Count - ((currentCloseNumber * 2) + space), 0)];
int max = bracket[bracket.Count - 1];
space = max - min - 1;
List<int> proc = new List<int>();
int firstIndex = -1;
int lastIndex = -1;
for (int ii = 0; ii < other.Count; ii++)
{
if (other[ii] > min && other[ii] < max)
{
proc.Add(other[ii]);
other[ii] = -1;
if (firstIndex == -1)
{
firstIndex = ii;
lastIndex = ii;
}
else
{
lastIndex = ii;
}
}
}
double leftPixel = firstIndex * widthEachChar;
double rightPixel = (lastIndex * widthEachChar) + widthEachChar;
DrawLine(canvas, currentCloseNumber, leftPixel,
rightPixel, lastLineAboveNotation * heightEachChar / PARTICLE_EACH_CHAR);
lastLineAboveNotation += 1;
currentOpenNumber -= currentCloseNumber;
currentCloseNumber = 0;
}
}
else
{
other.Add(i);
}
}
return lastLineAboveNotation + 1;
}
If someone got a more efficient code, please let us know!

C# Check for neighbours

I have a function to check neighbors of an array and if that element is equal with 1. X is for each neighbor found and v[l] is the position for each 0. I have a problem with this code each time gives me "Index was outside the bounds of the array" and i don't know what to do else.
public int modificari(int i,int j,int n,int m)
{
int x = 0;
v = new int[n];
l=0;
if (mat[i, j] == 1)
{
if (j++ < m)
{
if (mat[i, j++] == 1)
x++;
else
{
v[l] = i * n + j + 2;
l++;
}
}
if (j++ < m && i++ < n)
{
if (mat[i++, j++] == 1)
x++;
else
{
v[l] = (i + 1) * n + j + 2;
l++;
}
}
if (i++ < n)
{
if (mat[i++, j] == 1)
x++;
else
{
v[l] = (i + 1) * n + j + 1;
l++;
}
}
if (j-- >= 0 && i++ < n)
{
if (mat[i++, j--] == 1)
x++;
else
{
v[l] = (i + 1) * n + j;
l++;
}
}
if (j-- >= 0)
{
if (mat[i, j--] == 1)
x++;
else
{
v[l] = i * n + j;
l++;
}
}
if (j-- >= 0 && i-- >= 0)
{
if (mat[i--, j--] == 1)
x++;
else
{
v[l] = (i - 1) * n + j;
l++;
}
}
if (i-- >= 0)
{
if (mat[i--, j] == 1)
x++;
else
{
v[l] = (i - 1) * n + j + 1;
l++;
}
}
if (j < n && i-- >= 0)
{
if (mat[i--, j++] == 1)
x++;
else
{
v[l] = (i - 1) * n + j + 2;
l++;
}
}
if (x < 2 && x > 3)
return 1;
else
return random();
}
return x;
}
That is a total mess. It is very hard to follow, even for an experienced coder. Use of one letter variable names and inline ++ operators is usually discouraged for the sake of readability.
I've quickly tried to rewrite your function from my best guess of what you're trying to achieve. I'm hoping you can see a different way to approach the problem that suits you better.
NOTE: I did not test this code at all, it probably has compile errors.
public struct Point
{
public int X;
public int Y;
public Point( int x, int y )
{
X = x;
Y = y;
}
}
public class Whatever
{
// ...
// Here is a list of the positions of all the neighbours whose values are
// zero.
List<Point> zeroPositions = new List<Point>();
// ...
public int Modificari(int pointX, int pointY)
{
// Determine dimensions of array.
int height = mat.GetLength(0);
int width = mat.GetLength(1);
// Find the minimum and maximum positions bounded by array size. (So we
// don't try to look at cell (-1, -1) when considering the neighbours of
// cell (0, 0) for instance.
int left = Math.Max( pointX - 1, 0 );
int right = Math.Min( pointX + 1, width );
int top = Math.Max( pointY - 1, 0 );
int bottom = Math.Min( pointY + 1, height );
// This is the number of neighbours whose value is 1.
int oneCount = 0;
zeroPositions.Clear();
for( int y = top; y <= bottom; y++ )
{
for( int x = left; x <= right; x++ )
{
if( mat[x, y] == 1 )
{
oneCount++;
}
else if( mat[x, y] == 0 )
{
zeroPositions.Add( new Point( x, y ) );
}
}
}
return oneCount;
}
//...
}
Also I'd really advise you to try not to do too many things in a function. Try making a different function for getting positions of ones and for returning the number of zeros.

dragging issue in chess table

I have chess table and my elements are now moving according to rules .But when I drag out of rules my button is disappearing...How I can solve it ???
(red buttons are showing where can I go my elements)
for example knight is moving as rules now (if I don't pass over the red buttons there is no problem)but when I pass over the red places and if I drop there the knight disappears and red places turns back to their original color ( no more red places which indicates where my knight can go ). i tried to make debug but since i am new in c# and debugging i haven't solved the problem. i will be happy if u enlighten my way. how can i solve it? thanks
void btn_DragEnter(object sender, DragEventArgs e)
{
Button button = (Button)sender;
e.Effect = DragDropEffects.Move;
for (int x = 0; x <= 7; x++)
{
for (int y = 0; y <= 7; y++)
{
btn[x, y].Image = null;
if ((x + y) % 2 == 0)
btn[x, y].BackColor = Color.Black;
else
btn[x, y].BackColor = Color.White;
}
}
}
void btn_DragDrop(object sender, DragEventArgs e)
{
Button button = (Button)sender;
button.Image = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
int[] dizi = (int[])button.Tag;
int x = dizi[0];
int y = dizi[1];
for (int a = 0; a <= 7; a++)
{
for (int b = 0; b <= 7; b++)
{
btn[a, b].AllowDrop = false;
}
}
if ((x + 1 >= 0 && y + 2 <= 7) && (y + 2 >= 0 && x + 1 <= 7))
{
btn[x + 1, y + 2].BackColor = Color.Red;
btn[x + 1, y + 2].AllowDrop = true;
}
if ((x + 1 >= 0 && y - 2 <= 7) && (y - 2 >= 0 && x + 1 <= 7))
{
btn[x + 1, y - 2].BackColor = Color.Red;
btn[x + 1, y - 2].AllowDrop = true;
}
if ((x - 1 >= 0 && y + 2 <= 7) && (y + 2 >= 0 && x - 1 <= 7))
{
btn[x - 1, y + 2].BackColor = Color.Red;
btn[x - 1, y + 2].AllowDrop = true;
}
if ((x - 1 >= 0 && y - 2 <= 7) && (y - 2 >= 0 && x - 1 <= 7))
{
btn[x - 1, y - 2].BackColor = Color.Red;
btn[x - 1, y - 2].AllowDrop = true;
}
if ((x + 2 >= 0 && y + 1 <= 7) && (y + 1 >= 0 && x + 2 <= 7))
{
btn[x + 2, y + 1].BackColor = Color.Red;
btn[x + 2, y + 1].AllowDrop = true;
}
if ((x + 2 >= 0 && y - 1 <= 7) && (y - 1 >= 0 && x + 2 <= 7))
{
btn[x + 2, y - 1].BackColor = Color.Red;
btn[x + 2, y - 1].AllowDrop = true;
}
if ((x - 2 >= 0 && y + 1 <= 7) && (y + 1 >= 0 && x - 2 <= 7))
{
btn[x - 2, y + 1].BackColor = Color.Red;
btn[x - 2, y + 1].AllowDrop = true;
}
if ((x - 2 >= 0 && y - 1 <= 7) && (y - 1 >= 0 && x - 2 <= 7))
{
btn[x - 2, y - 1].BackColor = Color.Red;
btn[x - 2, y - 1].AllowDrop = true;
}
}
DoDragDrop is called only when actually dropping the piece. Your logic for determining where the piece can be dropped should be run when starting the drag, in MouseDown or MouseMove, before the call to DoDragDrop. It also seems you are clearing the red buttons in the DragEnter function. That also should be done in the MouseDown/MouseMove function, after the call to DoDragDrop.

Rectangle ArgumentOutOfRangeException Per-Pixel Collision

I've been trying to solve this problem but I really can't see what's wrong with the code. It's exactly the same as my other rectangles but it won't work.
Working Code: Everything in here works fine (more or less)
private void UpdateCollision()
{
// Uses built in rectangle intersect function to determine overlapping
Rectangle rectangle1;
Rectangle rectangle2;
Rectangle rectangle3;
// Creates 1 rectangle for player
rectangle1 = new Rectangle((int)player.Position.X, (int)player.Position.Y, player.Width, player.Height);
// Sets collision btw objs
for (int i = 0; i < enemies.Count; i++)
{
for (int j = 0; j < enemies2.Count; j++)
{
rectangle2 = new Rectangle((int)enemies[i].Position.X, (int)enemies[i].Position.Y, enemies[i].Width, enemies[i].Height);
rectangle3 = new Rectangle((int)enemies2[j].Position.X, (int)enemies2[j].Position.Y, enemies2[j].Width, enemies2[j].Height);
// Determines collision
if (IntersectPixels(rectangle1, playerTextureData, rectangle2, enemyTextureData) && player.PlayerAnimation.Active == true)
{
player.Health -= enemies[i].Damage;
enemies[i].Health = 0;
if (player.Health == 0)
AddMyExplosion(player.Position);
}
if (IntersectPixels(rectangle1, playerTextureData, rectangle3, enemy2TextureData) && player.PlayerAnimation.Active == true)
{
player.Health -= enemies2[j].Damage;
enemies2[j].Health = 0;
if (player.Health == 0)
AddMyExplosion(player.Position);
}
}
}
Non-working Code: The line where the exception pops up is where rectangle3 is defined
// Proj obj collision
for (int i = 0; i < projectiles.Count; i++)
{
for (int j = 0; j < enemies.Count; j++)
{
for (int k = 0; k < enemies2.Count; k++)
{
// Creates col det rectangles
rectangle1 = new Rectangle((int)projectiles[i].Position.X - projectiles[i].Width / 2, (int)projectiles[i].Position.Y - projectiles[i].Height / 2, projectiles[i].Width, projectiles[i].Height);
rectangle2 = new Rectangle((int)enemies[j].Position.X - enemies[j].Width / 2, (int)enemies[j].Position.Y - enemies[j].Height / 2, enemies[j].Width, enemies[j].Height);
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);
//Rectangle 3 is not working//
// Determines col
if (IntersectPixels(rectangle1, projectileTextureData, rectangle2, enemyTextureData))
{
enemies[j].Health -= projectiles[i].Damage;
AddImpact(projectiles[i].Position);
impactSound.Play();
projectiles[i].Active = false;
}
if (IntersectPixels(rectangle1, projectileTextureData, rectangle3, enemy2TextureData))
{
enemies2[j].Health -= projectiles[i].Damage;
AddImpact(projectiles[i].Position);
impactSound.Play();
projectiles[i].Active = false;
}
}
}
}
}
So if anyone could help me solve this I would be very grateful.
Typo. Change this line:
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);
to this:
rectangle3 = new Rectangle((int)enemies2[k].Position.X - enemies2[k].Width / 2, (int)enemies2[k].Position.Y - enemies2[k].Height / 2, enemies2[k].Width, enemies2[k].Height);

Categories

Resources