I am having a little problem here, I want to draw a vertical pyramid like this:
O
OO
OOO
OOOO
OOOOO
OOOO
OOO
OO
O
But I can't seem to figure out how to do it. All I get is:
O
OO
OOO
OOOO
OOOOO
OOOOOO
OOOOOOO
OOOOOOOO
OOOOOOOOO
Here is my code:
int width = 5;
for (int y = 1; y < width * 2; y++)
{
for (int x = 0; x < y; x++)
{
Console.Write("O");
}
Console.WriteLine();
}
There are ways to do this with two loops, but here is a way to do it with one, and without an if condition:
for (int y = 1; y < width * 2; y++)
{
int numOs = width - Math.Abs(width - y);
for (int x = 0; x < numOs; x++)
{
Console.Write("O");
}
Console.WriteLine();
}
use this code maybe useful
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication59
{
class Program
{
static void Main(string[] args)
{
int numberoflayer = 6, Space, Number;
Console.WriteLine("Print paramid");
for (int i = 1; i <= numberoflayer; i++) // Total number of layer for pramid
{
for (Space = 1; Space <= (numberoflayer - i); Space++) // Loop For Space
Console.Write(" ");
for (Number = 1; Number <= i; Number++) //increase the value
Console.Write(Number);
for (Number = (i - 1); Number >= 1; Number--) //decrease the value
Console.Write(Number);
Console.WriteLine();
}
}
}
}
Here is a minimalist method with only one loop and one ternary expression (?) instead of if:
int width = 5;
for (int y = 1; y < width * 2; y++)
Console.WriteLine(String.Empty.PadLeft(y < width ? y : width * 2 - y, 'O'));
Or a version without check:
for (int y = 1; y < width * 2; y++)
Console.WriteLine(String.Empty.PadLeft(Math.Abs(width * (y / width) - (y % width)), 'O'));
Related
Using unity to create a procedural map I'm getting the Error "Cs0161: not all code paths return a value" , I'm still pretty new to coding and I may have made some mistake.
I've tried google but the answers don't even make sense to me
yet
MapData GenerateMapData()
{
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, lacunarity, persistance, offset);
Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight <= regions[i].height)
{
colourMap[y * mapChunkSize + x] = regions[i].colour;
break;
}
}
}
return new MapData(noiseMap, colourMap);
}
}
Error CS0161 'MapGenerator.GenerateMapData()': not all code paths return a value Assembly-CSharp
After the for loops you should also return a value. See the code below and the comment at the bottom of the method:
MapData GenerateMapData()
{
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, lacunarity, persistance, offset);
Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight <= regions[i].height)
{
colourMap[y * mapChunkSize + x] = regions[i].colour;
break;
}
}
}
return new MapData(noiseMap, colourMap);
}
// You should also return something here
}
It is theoretically possible that mapChunkSize can have a value of 0 (zero) and it will not enter the first for loop at all. That's why you need a return statement at the bottom as well.
The reason why you are receiving that error is because your return statement is inside the for loops. More specifically, it can happen that neither of the loops execute (e.g. mapChunkSize == 0. Then 0 isn't less than 0 and the program doesn't enter the for loops) and that thus nothing gets returned. So either move the return outside the loops or add another return outside the loops.
MapData GenerateMapData()
{
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, lacunarity, persistance, offset);
Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight <= regions[i].height)
{
colourMap[y * mapChunkSize + x] = regions[i].colour;
break;
}
}
}
/*return new MapData(noiseMap, colourMap); //uncommenting this might still leave you with the functionality you want */
}
return new MapData(noiseMap, colourMap);
}
you are not returning any thing outside the first loop, try to evaluate values inside the loops and then return from outside the loop.
for (int y = 0; y < mapChunkSize; y++)
{
for (int x = 0; x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for (int i = 0; i < regions.Length; i++)
{
if (currentHeight <= regions[i].height)
{
colourMap[y * mapChunkSize + x] = regions[i].colour;
break;
}
}
}
return new MapData(noiseMap, colourMap);
}
add return statement here
The problem is to make a program the flips a 2D (2 by 2) array either horizontally(H) or vertically(V), depending on the input the user puts. For example, if the user puts "HHHVVHVHV", it means to flip 5 times horizontally, and 4 times vertically. The code I attached below works, but I am not sure if there is a built-in method in C# to flip arrays or an easier way to do it.
using System;
using System.Linq;
namespace _2019JuniorQ4
{
class Program
{
static void Main(string[] args)
{
//Varables
int[,] grid = new int[2, 2] { { 1, 2 }, { 3, 4 } };
int[,] flippedGrid = new int[2, 2];
string input = "";
int h = 0;
int v = 0;
int flipHorizontal = 0;
int flipVertical = 0;
//Input
input = Console.ReadLine();
//Count number of times
for (int i=0; i<input.Length; i++)
{
if (input[i] == Convert.ToChar("H"))
{
h++;
}
else if(input[i] == Convert.ToChar("V"))
{
v++;
}
}
//Process
flipHorizontal = h % 2;
flipVertical = v % 2;
//Vertical flip
if (flipVertical == 1)
{
for (int y = 0; y < 2; y++)
{
for (int x = 1; x >= 0; x--)
{
flippedGrid[y, Math.Abs(x - 1)] = grid[y,x];
}
}
grid = flippedGrid.Clone() as int[,];
}
//Horizontal Flip
if (flipHorizontal == 1)
{
for (int x = 0; x < 2; x++)
{
for (int y = 1; y >= 0; y--)
{
flippedGrid[Math.Abs(y - 1), x] = grid[y,x];
}
}
grid = flippedGrid.Clone() as int[,];
}
//Output
for (int x=0; x<2; x++)
{
for (int y=0; y<2; y++)
{
Console.Write(grid[x,y]+" ");
}
Console.WriteLine();
}
}
}
}
I got the following codes:
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
return boos[i, j, k];
}
The code above is inefficient so i convert it to one dimensional array:
Boo[] boosone;
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
if (boosone == null)
{
boosone = new Boo[8 * 8 * 8];
int num = 0;
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
for (int z = 0; z < 8; z++)
{
boosone[num] = boos[x, y, z];
num++;
}
}
}
}
return boosone[?];
}
How can I get the Boo (from the same position like in multidimensional array j k l) from the one dimensional array boosone?
int index = (8 * 8 * i) + (8 * j) + k;
return boosone[index];
Not really sure why you're saying that the first 3D array is not efficient (I mean, have you actually noticed a particularly heavy slowdown when using it?), but you can do that with some simple offset calculations.
First of all, if you target the latest C# version, you can replace the whole copy function with just two lines, and your code would then look like this:
using System;
using System.Runtime.InteropServices;
Boo[] boosone;
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
if (boosone == null)
{
boosone = new Boo[boos.Length];
MemoryMarshal.CreateSpan(ref boos[0, 0, 0], boosone.Length).CopyTo(boosone);
}
return boosone[boos.GetLength(1) * boos.GetLength(2) * i + boos.GetLength(2) * j + k];
}
If you don't want to use the MemoryMarshal class for some reason, you could also use LINQ to flatten your 3D array, although this approach is much less efficient:
boosone = boos.Cast<Boo>().ToArray();
Accessing a multi dimensional array isn't any slower then accessing a single dimension array, in fact they are both stored in memory exactly the same way. It's not what you are doing, it's how you are doing it.
If you want to wrap either array in a trivial method, give the compiler a hint that it can be inline
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Boo GetMe(int i, int j, int k)
{
return boos[i, j, k];
}
On saying that, this method does absolutely nothing and has no advantage then just using the array indexer.
If you want to work with segments of an array with out the overhead of reallocation, consider using Span<T> or Memory<T> or ArraySegment
At about this point I would write example code, however as I have no idea what you are doing, it's hard to guess what you need.
What I suggest, is download BenchmarkDotNet, and start profiling your code to work out what is the most efficient and performant way to do what you desire, don't guess...
Why don't you look at jagged arrays which provide better performance? I did a test (under RELEASE configuration) which showed that you wrapper is twice faster than the d3 array, but jagged is 3 times faster than the d3 array.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace ArrayWrapper
{
class ArrayPerformanceTest
{
int xSize = 2;
int ySize = 3;
int zSize = 4;
int count = 100000000;
int delay = 500;
static void Main(string[] args)
{
new ArrayPerformanceTest().Run();
}
private void Run()
{
var d3Array = CreateD3Array();
var wrapped = GetD1Adapter(d3Array);
var jagged = GetJaggedArray(d3Array);
Thread.Sleep(delay);
TestD3Array(d3Array);
Thread.Sleep(delay);
TestWrappedArray(wrapped);
Thread.Sleep(delay);
TestJaggeddArray(jagged);
Thread.Sleep(delay);
}
private int[,,] CreateD3Array()
{
var rectangular = new int[xSize, ySize, zSize];
int i = 7;
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
rectangular[x, y, z] = ++i;
return rectangular;
}
private int[] GetD1Adapter(int[,,] d3Array)
{
return d3Array.Cast<int>().ToArray();
}
private int[][][] GetJaggedArray(int[,,] d3Array)
{
var xSize = d3Array.GetUpperBound(0) + 1;
var ySize = d3Array.GetUpperBound(1) + 1;
var zSize = d3Array.GetUpperBound(2) + 1;
var jagged = new int[xSize].Select(j => new int[ySize].Select(k => new int[zSize].ToArray()).ToArray()).ToArray();
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
jagged[x][y][z] = d3Array[x, y, z];
return jagged;
}
private void TestD3Array(int[,,] d3Array)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = d3Array[x, y, z];
sw.Stop();
Console.WriteLine($"{nameof(d3Array),7} {sw.ElapsedTicks,10}");
}
private void TestWrappedArray(int[] wrapped)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = wrapped[x * ySize * zSize + y * zSize + z];
sw.Stop();
Console.WriteLine($"{nameof(wrapped),7} {sw.ElapsedTicks,10}");
}
private void TestJaggeddArray(int[][][] jagged)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = jagged[x][y][z];
sw.Stop();
Console.WriteLine($"{nameof(jagged),7} {sw.ElapsedTicks,10}");
}
}
}
Output:
d3Array 15541709
wrapped 8213316
jagged 5322008
I also analysed CPU usage.
It is of the same rate for all 3 approaches.
I have this code to read a 1x3 matrix (1 5 9) from a text file and make a 3x3 matrix out of it.
The output matrix should be:
1 0 0
0 5 0
0 0 9
using a loop (and conditions - if needed). The closest I got is:
1 0 0
5 0 0
9 0 0.
Here's my code:
for (int x = 0; x <= 2; x++)
{
for (int y = 0; y <= 2; y++)
{
sw.Write("{0} ", matrix[x, y]);
sw.WriteLine();
}
}
sw.WriteLine();
sw.Close();
Here is how I think you can do it.
Let's consider matrixA the original matrix and matrixB the final matrix.
Here is the logic
//Convert 1x3 into 3x3
for (int x = 0; x <= 2; x++)
{
matrixB[x,x]=matrixA[x];
}
//Display Matrix
for (int x = 0; x <= 2; x++)
{
for (int y = 0; y <= 2; y++)
{
sw.Write("{0} ", matrix[x, y]);
sw.WriteLine();
}
}
sw.WriteLine();
sw.Close();
Here is a solution using Linq. Make sure you add System.Linq to your using clause. I did see that you want to use loops. I'll leave this here anyway for reference as a more idiomatic way of expressing the solution.
var matrix1 = new int[] {1,5,9};
var matrix3 = matrix1.Select ((v, i) => {
var n = new int[matrix1.Length];
n [i] = v;
return n;
});
foreach (var v in matrix3)
Console.WriteLine ("{0} {1} {2}", v[0],v[1],v[2]);
Currently working on writing a Conways life in C# for class. I've been taking small steps to get a hang out the language and game programming in general and have hit a snag in printing my 2D char array. Currently I'm using GetLength - 1 to not go over the bound but it fails to print out the last chars in the array.
What my initial file looks like
+*++
++*+
****
After its read into placed into Char (i believe)
*
*
****
What ends up printed
*
**
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace ConwaysLife
{
class Program
{
static char[,] universe;
static void bigBang(int h, int w, List<string> grid)
{
universe = new char[h,w];
int row = 0;
foreach (string line in grid)
{
for (int i = 0; i < line.Length; i++)
{
if (line.ToCharArray()[i] == '*')
{
universe[row, i] = '*';
}
}
row++;
}
}
//How I'm attempting to print out my 2D char array
static void offspring()
{
StringBuilder cellLine = new StringBuilder();
for (int y = 0; y < universe.GetLength(1)-1; y++)
{
for (int x = 0; x < universe.GetLength(0)-1; x++)
{
Console.Write(universe[y, x]);
}
Console.WriteLine();
}
//pause
Console.ReadLine();
}
static void Main(string[] args)
{
List<string> tempLine = new List<string>();
//Console.WriteLine("File Path?");
int width = 0;
int height = 0;
//read file into List
using (StreamReader r = new StreamReader("life.txt"))
{
while (r.Peek() >= 0)
{
tempLine.Add(r.ReadLine());
//compare current width to new width
if (tempLine[height].Length >= width) { width = tempLine[height].Length; }
//increase height when going to next row
height++;
}
bigBang(height, width, tempLine);
}
offspring();
}
}
}
Update Offspring()
static void offspring()
{
StringBuilder cellLine = new StringBuilder();
for (int x = 0; x <= universe.GetLength(1); x++)
{
for (int y = 0; y <= universe.GetLength(0); y++)
{
Console.Write(universe[x, y]);
}
Console.WriteLine();
}
//pause
Console.ReadLine();
}
You have an off-by-one error in your offspring function. Note that you're doing it correctly in the bigBang function.
You are looping while x < GetLength()-1. You just need x < GetLength(), because that excludes the case when x == GetLength().
An analagous loop:
for (i = 0; i < 4; i++)
Console.WriteLine(i);
Output:
0
1
2
3
I'm not familiar with the game principles, but there's a problem in your offspring method.
y < universe.GetLength(1)-1
This translates to y < 3 - 1 or y < 2, making your iteration go from y = 0 to 1.
To fix, simply remove the two occurences of -1.
for (int y = 0; y < universe.GetLength(1); y++)
{
for (int x = 0; x < universe.GetLength(0); x++)
{
In addition, you have your indices reversed when you access universe.
Console.Write(universe[y, x]);
There you're using the y variable to access the row, and x for the column. The inverse should be done like this:
Console.Write(universe[x, y]);
Giving a final output of
++*
*+*
+**
++*
While I'll delve deeper as to why it wasn't working as I expected it to I simply passed the sizes of the array when I created it to my offspring() and used those values when printing. Once that small change was the done the output came out as expected.
*
*
****