I'd like to know how to write a program in 2D array to exchange the elements of main diagonal with secondary diagonal then print the result
like this
3 2 7
4 5 3
2 8 9
and the result show like this
7 2 3
4 5 3
9 8 2
Actually it's not a very specific problem, but as I don't see the part where you're stuck I'll try to explain a whole example to you:
static int[,] GetDiagonallySwitched(int[,] oldMatrix)
{
var newMatrix = (int[,])oldMatrix.Clone();
for (var i = 0; i < oldMatrix.GetLength(0); i++)
{
var invertedI = oldMatrix.GetLength(0) - i - 1;
newMatrix[i, i] = oldMatrix[i, invertedI];
newMatrix[i, invertedI] = oldMatrix[i, i];
}
return newMatrix;
}
First of all I'm cloning the old matrix, because a few values actually remain the same. Then I switch the values from the left side to the right side. I'm doing this with the invertedI, which basically is i from the other side - so that in the end the cross is mirrored and it seems as though the lines switched. This is working for any size of the matrix.
For the printing: If you actually want to print it bold, you'll have to use a RTB in WinForms, but I don't guess this was part of your question. Otherwise you could use this code to print the matrix:
static void Print(int[,] switched)
{
for (var y = 0; y < switched.GetLength(0); y++)
{
for (var x = 0; x < switched.GetLength(1); x++)
Console.Write(switched[y, x]);
Console.WriteLine();
}
}
I hope I could help you.
Related
I'm currently trying to create a battleships console application. I've very new to c# but I'm almost there now there's just issue.
What I'm trying to do is replace a string with H or M when a ship is hit the works fine the only issue I have is when the H or M is inserted it doesn't replace the character in its place and it just moves the characters alone, for example if I have 5 characters in a row it like so: 0 0 0 0 0 it would insert the H or M and show: M0 0 0 0 0
I've been trying all sorts to fix this but as I said my knowledge is very limited.
Ints and Grid creation:
int gridSize = 10;
int BattleShip = 5;
int Destroyer1 = 4;
int Destroyer2 = 4;
int Row;
int Column;
char[,] Vgrid = new char [gridSize, gridSize];
This generates the grid:
for (Row = 0; Row < gridSize; Row++)
{
Console.WriteLine();
Console.Write("{0} | ", GridNumber++);
for (Column = 0; Column < gridSize; Column++)
Console.Write(Vgrid[Column, Row] + "~ ");
}
This code controls the H or M replacing:
if (grid[temp, temp1] == Destroyer1 || grid[temp, temp1] == Destroyer2 || grid[temp, temp1] == BattleShip)
{
Console.WriteLine("HIT!");
Hit++;
Vgrid[temp, temp1] = 'H';
}
else
{
Console.WriteLine("MISS!");
Miss++;
Vgrid[temp, temp1] = 'M';
}
Is there a way I can do this? I just want to be able to replace the character in the grid with the H or M characters.
This grid is actually an overlay as the actual grid is an int and that is where the ships are plotted, this is the only way I thought I can use letters to signify a hit instead of numbers and keep the ships hidden to the players.
Attempting to alter the output of the Console window directly isn't necessarily the best approach for what you're wanting to achieve. Ideally, we should control what we write to the window, rather than try and control the window directly.
A simpler idea to achieve your goal might be to store two grids, one for your ships and another one for your shots. This allows you to separate what you draw to the console window from what you use to check if the player has landed a shot easily, keeping your ships hidden.
Firstly, let's create our setup:
int gridSize = 10;
int BattleShip = 5;
int Destroyer1 = 4;
int Destroyer2 = 4;
int[,] shipGrid = new int[gridSize, gridSize];
char[,] shotGrid = new char[gridSize, gridSize];
The big change is the grids - one for the ships, and another for the shots. We use the same gridSize variable to make sure that the grids are exactly the same size. This is important to make sure that the two grids line up exactly.
Then, we'll set our default values for our shotGrid. We can do this with a simple method that just sets every value to the default, in this case '~':
public void CreateShotGridDefaultValues ()
{
for (int y = 0; y < shotGrid.GetLength(1); y++)
{
for (int x = 0; x < shotGrid.GetLength(0); x++)
{
shotGrid[x, y] = '~';
}
}
}
Next, to check if a player has landed a shot, we use the shipGrid to check if the player's selection relates to a ship, but we update the shotGrid with the information we want to draw to the console window:
public void CheckPlayerShot(int xCoordinate, int yCoordinate)
{
if (shipGrid[xCoordinate, yCoordinate] == Destroyer1 || shipGrid[xCoordinate, yCoordinate] == Destroyer2 || shipGrid[xCoordinate, yCoordinate] == BattleShip)
{
Console.WriteLine("HIT!");
Hit++;
shotGrid[xCoordinate, yCoordinate] = 'H';
}
else
{
Console.WriteLine("MISS!");
Miss++;
shotGrid[xCoordinate, yCoordinate] = 'M';
}
}
Then, we draw out the shotGrid to the console window as follows:
public void DrawGrid()
{
Console.WriteLine();
for (int y = 0; y < shotGrid.GetLength(1); y++)
{
string currentLine = $"{y + 1} | ";
for (int x = 0; x < shotGrid.GetLength(0); x++)
{
char shot = shotGrid[x, y];
currentLine += shot.ToString() + " ";
}
Console.WriteLine(currentLine);
}
Console.WriteLine();
}
This method is a little different to yours, so let me explain a little further. The idea for this method is to build up the information we want to write to the console window one line at a time, rather than draw out every character one at a time. This prevents us from needing to change the console window output directly.
To achieve this, we use two loops, just like you did. The second for() loop iterates through the row's grid cells, and adds them to the currentLine string. Once we've finished a row, we just write out that string to the console window all at once.
With all that in place, you just need call the DrawGrid() method whenever you want to update the grid in the console window. To better understand when and where the best time and place to update the window might be, requires a better understanding of Game Loops. This page should be a terrific start on that path..
Edit: Updated answer to reflect comments.
You could use
Console.SetCursorPosition(Int32, Int32) Method
Sets the position of the cursor.
Or you could just keep everything in a matrix and redraw the screen on change
I am trying to complete a game over condition for a peg solitaire game i am writing.
I have all of the movements and pieces removing as they should.
Each piece is held within a 2d array as an Ellipse UI Ellement and when a piece is taken it is replaced with a border Ui Element.
I have started to use a method adapted from a Stackoverflow post that scans the 8 adjacent squares around the array element.
public static IEnumerable<T> AdjacentElements<T>(T[,] arr, int row, int column)
{
int rows = arr.GetLength(0);
int columns = arr.GetLength(1);
for (int j = row - 1; j <= row + 1; j++)
for (int i = column - 1; i <= column + 1; i++)
if (i >= 0 && j >= 0 && i < columns && j < rows && !(j == row && i == column))
yield return arr[j, i];
}
}
The method called once a piece is taken.
var results = AdjacentElements(grid, 3, 3);
foreach (var result in results)
Debug.WriteLine(result);
When it encounters an ellipse it should check the squares directly above,below,left and right of the Ellipse, at the moment is all 8 squares, i only need four (top, bottom, left and right).
I am using grid reference 3,3 to test at the moment and it is printing out as expected but for all 8 squares.
If any of the four squares in turn encounter and ellipse the next square in a straight line should be a Border in order to be a possible move.
For example:
Circle 1 is the Ellipse being checked.
The circles below,left and right are ignored.
The Cirle 2 is chosen as Square 3 is empty.
This would produce a valid move so the game would continue.
If no valid move is found the game will end.
I not sure how to proceed with this, I was thinking of putting the method call inside a nested for loop to go over every element but I'm thinking it would be very inefficient.
var results = AdjacentElements(grid, i, j);
foreach (var result in results)
//condition here
I don't think i truly understand what you want to do. However, yes you could do nested loops. but sometimes its just easier to poke at it
Given some array x, y
var x = 23;
var y = 3;
Exmaple
var checks = List<Point>();
checks.Add(new Point(x+1,y));
checks.Add(new Point(x-1,y));
checks.Add(new Point(x,y+1));
checks.Add(new Point(x,y-1));
foreach(var check in checks)
//If Bounds check
//do what you need to do
I would like to know if this simulator works as it should because I don't think these are logical answers, but can't capture mistake either.
I have written a simulator for the following game(Given a deck of cards and 1 point) to find most optimal strategy(what is dealers highest card to continue game)
1. Dealer picks a card and shows it to you(Dealer can't pick Joker)
2. You decide whether to play or no
3.1. If you don't play you get current points and finish game
3.2. If you play you pick a Card
3.2.1. If your card is higher you get double points and go back to step 1
3.2.2. If your and dealer's cards are equal you go back to step 1
3.2.3. If dealer's card is higher you lose all points and finish
The simulation shows win coefficient for choosing each MAX card to play.It shows these numbers which is highly doubtful to me.I expected it to grow to 1.5 till 7 and then go back to 1.
(First-Win/number of simulations,Second-Max card dealer can get for you to continue game)
1 -1
1.0853817 0
1.1872532 1
1.3126581 2
1.4672619 3
1.6704736 4
1.9485809 5
2.2674231 6
2.9993735 7
3.5692085 8
4.3581477 9
4.0109722 10
2.3629856 11
0 12
Here's C# code:
using System;
namespace Codeforces
{
class Program
{
static int[] k = new int[54];
static Random rand = new Random();
static long Doubling(int i, long f)
{
int d = rand.Next(52);
if (k[d] > i) return f;
int ch = d;
while (ch == d) ch = rand.Next(54);
if (k[d] > k[ch]) return 0;
if (k[d] == k[ch]) return Doubling(i, f);
return Doubling(i, f * 2);
}
static void Main(string[] args)
{
for (int i = 0; i < 54; i++) k[i] = i / 4;
for (int i = -1; i < 13; i++)
{
long sum = 0;
for (int j = 0; j < 1e7; j++)
{
sum += Doubling(i, 1);
}
Console.WriteLine(sum / 1.0e7 + " " + i);
}
}
}
}
I'm not a C# programmer, but it looks like your basic approach is mostly correct. I would recommend using a loop rather than recursion.
Your problem description is vague regarding the value of jokers and whether dealer discards jokers when drawn or magically just doesn't draw them—you seem to have gone for the latter if I'm reading your code correctly.
It also appears that the way you implemented the recursion implicitly replaces cards in the deck after each play of the game rather than playing through the deck.
When I implemented this independently in another language, I got comparable results. Looks to me like your intuition is wrong.
I apologize if this question is too vague because I haven't actually built out any code yet, but my question is about how to code (perhaps in C# in a Unity3d script, but really just generically) the dynamically changing unit depth/width in total war games.
In TW games, you can click and drag to change a unit from an nx2 formation to 2xn formation and anything in between. Here's a video (watch from 15 seconds in to 30 seconds in):
https://www.youtube.com/watch?v=3aGRzy_PzJQ
I'm curious, generically speaking, about the code that would permit someone to on the fly exchange the elements of an array like that. I'm assuming here that the units in the formation are elements in an array
so, you might start with an array like this:
int[,] array = new int[2, 20];
and end up with an array like this:
int[,] array = int[20, 2];
but in between you create the closest approximations, with the last row in some cases being unfilled, and then the elements of that last row would have to center visually until the column width was such that the number of elements in all the rows are equal again.
It kind of reminds me of that common intro to programming problem that requires you to write to the console a pyramid made of *'s all stacked up and adding one element per row with spaces in between, but a lot more complicated.
Most of the lower-tech formation tactics games out there, like Scourge of War just let you choose either Line Formation (2 rows deep) or column formation (2 columns wide), without any in between options, which was perhaps an intentional design choice, but it makes unit movement so awkward that I had to assume they did it out of technical limitations, so maybe this is a hard problem.
I wrote some code to clarify the question a bit. The method form() takes parameters for the number of units in the formation and the width of the formation, without using an array, and just prints out the formation to the console with any extra men put in the last row and centered:
x = number of men
y = width formation
r = number of rows, or depth (calculated from x and y)
L = leftover men in last row if y does not divide evenly into x
Space = number spaces used to center last row
form() = method called from the class Formation
I figured it should take the depth and number of men because the number of men is set (until some die but that's not being simulated here) and the player would normally spread out the men to the desired width, and so the number of rows, and number of men in those rows, including the last row, and the centering of that last row, should be taken care of by the program. At least that's one way to do that.
namespace ConsoleApplication6
{
class Formation
{
public int x;
public int y;
public Formation(int x, int y)
{
this.x = x;
this.y = y;
}
public void form()
{
int r = x / y;
int Left = x % y;
int Space = (y - Left)/2;
for (int i = 0; i < r;i++)
{
for (int j = 0; j < y; j++)
{
Console.Write("A");
}
Console.WriteLine();
if (i == r - 1)
{
for (int m = 0; m < Space; m++)
{
Console.Write(" ");
}
for (int k = 0; k < Left; k++)
{
Console.Write("A");
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("enter the number of men: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("enter the formation width: ");
int b = Convert.ToInt32(Console.ReadLine());
Formation testudo = new Formation(a,b);
testudo.form();
Console.ReadKey();
}
}
}
So, I think what I'm trying to do to improve this is have the above code run repeatedly in real time as the user inputs a different desired width (y changes) and men die (x changes)
But, if it were actually to be implemented in a game I think it would have to be an array, so I guess the array could take the x parameter as its max index number and then i would do a kind of for loop like for(x in array) or whatever print x instead of just console logging the letter A over and over
I am writing an application in Visual Studio Express [C#], and I need to display 12 ColorGrids [128 x 128] at the same time, in realtime.
This is how I setup my chart:
tChart1.Aspect.View3D = false;
tChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
tChart1.Legend.Visible = false;
tChart1.Axes.Bottom.Title.Text = "R";
tChart1.Axes.Bottom.SetMinMax(0, 127);
tChart1.Axes.Bottom.Increment = 20;
tChart1.Axes.Left.Title.Text = "D";
tChart1.Axes.Left.SetMinMax(0, 127);
And then I init the ColorGrid like this:
for (int d = 0; d < 128; d++)
{
for (int r = 0; r < 128; r++)
{
ColorGrid.Add(r, 0, d);
}
}
And then, in realtime, all I do is I update the YValues in some for-loop which covers the complete 128 x 128 range:
ColorGrid.YValues[index] = value;
And after the for loop, I call:
ColorGrid.BeginUpdate();
ColorGrid.EndUpdate();
I currently have this for 12 TChart controls, which are displayed together on a Form.
I also tried combining the 12 charts into one big chart, by plotting 12 graphs as a 6 x 2 "sub-plot" graph, and that only made a small performance difference.
Is there a way to get 10+fps with:
either 12 separate [128 x 128] graphs, or one [128*6 x 128*2] graph???
If I have left anything unclear, please let me know :-)
Thank you
JD
To improve the ColorGrid drawing time is a feature request already present in Steema's wish list (TF02016286).
Also note that, in general, as more points and elements of the chart to be drawn (grid lines, gradients, etc) more time is needed to draw the chart. So I'm not sure if it can be improved to the point you require.
A tip I don't see implemented in your example is to hide the ColorGrid Pen. This improves a bit the performance:
ColorGrid.Pen.Visible = false;
Also note ColorGrid.BeginUpdate() and ColorGrid.EndUpdate() are thought to be called before and after Clearing and repopulating the series respectively, not both together and after modifying the series values.