I'm creating a battleship field and I have created a method that creates spots based off of random parameters. The spots would be like the "1a", "2a" setup.
Here's what it looks like when you call it
ships.append(place_ship(ships, randint(2,3), letter, str(randint(1,4)), random.choice([True,False])))
randint(2,3) refers to the length of the ship, the random choice parameter is whether the boat is vertical or not, the letter refers to the random letter from this:
letter = ''
while letter != "a" and letter != "b" and letter != "c":
letter = random.choice(string.ascii_lowercase)
The method that creates it is place_ships:
def place_ship(ships, length, x, y, vert):
idk = {}
for i in range(length):
square = y+x
if vert:
x = chr(ord(x) + 1)
else:
y = str(int(y) + 1)
idk[i] = square
return idk
My question is how to place the ships without having any of the spots cross ships.
Here is an example of what the locations in a list look like:
['2c', '2d', '3c', '4c', '2c', '2d']
So 2c,2d is a ship 3c,4c, then 2c,2d
I've tried to do the following, but it only checks the first ship
for i in all_ship_loc:
occurence = all_ship_loc.count(i)
while occurence > 1:
place_ship(ships, randint(2,3), letter, str(randint(1,4)),random.choice([True,False]))
Thanks!
You may want to cretate a dictionary for every possible place, so you check if the generated position is already occuped.
dict = { "a1" : True } # True is occuped
Or you could use a list but with only the occuped places.
You might store a matrix of occupied places (values 0,1). Placing a ship occupies some elements (spots where the ship is located, adjacent etc.). For a given ship size, and a given row/column you easely can find out amount of positions available. So your alogorithm may be as follows:
starting from biggest ship
randomly choose a direction (horisontal/vertical)
enumerate positions available in that direction
if none available, reposition some last ships
choose a random position within available set, mark corresponding spots occupied
Related
I have some C++ code that picks a random item from a list. I need it to weight that randomness so that an item at place "n" has a chance equal to x/n where "x" is the chance that item one in the list will be selected. My current code is like this:
srand(time(NULL));
string a[≈9000] = {"String#1", "String#2", . . ., "String #≈9000"};
int value = rand() % ≈9000;
cout << a[value]
Note that the number notated as "≈9000" is a precise integer obscured for confidentiality. Variable names may be changed.
How can I weight it? I've come up with an equivalent formula
List B[≈9000] = "Item 'n' of 'a' times ≈9000 ÷ n"
Though you might notice that that isn't accurate CPP notation. Do y'all have any ideas how I can implement this?
This is not possible.
You need somehow to allow a variation on your conditions to have a proper distribution.
I have been working on License Plate Recognition based on github repository
https://github.com/MicrocontrollersAndMore/OpenCV_3_License_Plate_Recognition_Cpp
but I need to detect small characters. but I can't figure it out.
I think I need to change on the size checking but I can't figure it out.
https://github.com/MicrocontrollersAndMore/OpenCV_3_License_Plate_Recognition_Cpp/blob/master/DetectChars.cpp
bool checkIfPossibleChar(PossibleChar &possibleChar) {
// this function is a 'first pass' that does a rough check on a contour to see if it could be a char,
// note that we are not (yet) comparing the char to other chars to look for a group
if (possibleChar.boundingRect.area() > MIN_PIXEL_AREA &&
possibleChar.boundingRect.width > MIN_PIXEL_WIDTH && possibleChar.boundingRect.height > MIN_PIXEL_HEIGHT &&
MIN_ASPECT_RATIO < possibleChar.dblAspectRatio && possibleChar.dblAspectRatio < MAX_ASPECT_RATIO) {
return(true);
} else {
return(false);
}}
AND
double dblDistanceBetweenChars = distanceBetweenChars(possibleChar, possibleMatchingChar);
double dblAngleBetweenChars = angleBetweenChars(possibleChar, possibleMatchingChar);
double dblChangeInArea = (double)abs(possibleMatchingChar.boundingRect.area() - possibleChar.boundingRect.area()) / (double)possibleChar.boundingRect.area();
double dblChangeInWidth = (double)abs(possibleMatchingChar.boundingRect.width - possibleChar.boundingRect.width) / (double)possibleChar.boundingRect.width;
double dblChangeInHeight = (double)abs(possibleMatchingChar.boundingRect.height - possibleChar.boundingRect.height) / (double)possibleChar.boundingRect.height;
// check if chars match
if (dblDistanceBetweenChars < (possibleChar.dblDiagonalSize * MAX_DIAG_SIZE_MULTIPLE_AWAY) &&
dblAngleBetweenChars < MAX_ANGLE_BETWEEN_CHARS &&
dblChangeInArea < MAX_CHANGE_IN_AREA &&
dblChangeInWidth < MAX_CHANGE_IN_WIDTH &&
dblChangeInHeight < MAX_CHANGE_IN_HEIGHT) {
vectorOfMatchingChars.push_back(possibleMatchingChar); // if the chars are a match, add the current char to vector of matching chars
}
Thanks a lot in Advance.
You should first debug to see at which conditions the two A, A fails.
The MIN_PIXEL_AREA, MIN_PIXEL_WIDTH & MIN_PIXEL_HEIGHT may not be able to accomodate the small size A.
In second code snippet you provided, change the syntax of if statement from
if(condition1 && cond2 &&...)
to syntax
if(condition1) {if(codition2) {....}}. This will tell you where these condition fails.
Finally, in second snippet, a lot of conditions to check if the bounding rect is a character depends a lot on what kind of character is seen in past. Since in your case, the character AA differs in size, distance and direction(vertical) as well. Thus it would be better to reinitialize for AA instead of using previous characters, or some more conditions should be added for validating characters.[Like if both height and width decreased]
Once you know which conditions fails in step 2 and why, making relevant changes of step 3 should be simple.
Edit:
I looked further through the repo, and checked function findVectorOfVectorsOfMatchingChars and findVectorOfMatchingChars.
Analysis of findVectorOfMatchingChars function: This function takes a possibleChar and checks if this char is close(when all if condition passes) match with any of the possibleChar of vectorOfChars. If there is a match, store all matches together and return the results
Analysis of findVectorOfVectorsOfMatchingChars function: This function picks any possibleChar from vectorOfPossibleChars and finds all it matches using findVectorOfMatchingChars. If a good match is found, this function calls itself using (vectorOfPossibleChars - matchedPossibleChars).
Now, here is the problem.
Lets say each possibleChar is a vertex of the graph G and there is an edge between two possibleChar iff they satisfy the condition defined in findVectorOfMatchingChars function.
Now, lets say we have a graph with A,B,C,D,X as possibleChar vertex with X close enough to A,B,C,D but A,B,C,D are just far enough of each other to not be considered a close match.
Now let's apply findVectorOfVectorsOfMatchingChars on this vector of possibleChars.
Option 1: If we choose X first, we find A,B,C,D as its matching possibleChar and thus we get all possibleChar.
Option 2: If we choose A first, we find X to be matching possibleChar of A, but not B,C,D. Thus we remove A,X from vectorOfPossibleChars and reapply findVectorOfVectorsOfMatchingChars on B,C,D. Now, since there is no match between B,C,D, we end up with no match for B, or C or D.
Solution to rectify:
Create a graph class and register each possibleChar in it as Vertex. Make edges between each pair of vertex using conditions defined in findVectorOfMatchingChars.
You may need to customize conditions to incorporate the edges between other vertices and the 2 A's vertex. For this, you should use more datasets, so that the condtion you create or changing of threshold is not too generic to accomodate non-license plate chars.
Find connected tree in the graph to find all the characters. This may add all possibleChars. TO avoid that, you can limit addition using weighted edge.
I'm writing a program that will balance Chemistry Equations; I thought it'd be a good challenge and help reinforce the information I've recently learned.
My program is set up to use getline(cin, std::string) to receive the equation. From there it separates the equation into two halves: a left side and right side by making a substring when it encounters a =.
I'm having issues which only concerns the left side of my string, which is called std::string leftSide. My program then goes into a for loop that iterates over the length of leftSide. The first condition checks to see if the character is uppercase, because chemical formulas are written with the element symbols and a symbol consists of either one upper case letter, or an upper case and one lower case letter. After it checks to see if the current character is uppercase, it checks to see if the next character is lower case; if it's lower case then I create a temporary string, combine leftSide[index] with leftSide[index+1] in the temp string then push the string to my vector.
My problem lies on the first iteration; I've been using CuFe3 = 8 (right side doesn't matter right now) to test it out. The only thing stored in std::string temp is C. I'm not sure why this happening; also, I'm still getting numbers in my final answer and I don't understand why. Some help fixing these two issues, along with an explanation, would be greatly appreciated.
[CODE]
int index = 0;
for (it = leftSide.begin(); it!=leftSide.end(); ++it, index++)
{
bool UPPER_LETTER = isupper(leftSide[index]);
bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);
if (UPPER_LETTER)// if the character is an uppercase letter
{
if (NEXT_LOWER_LETTER)
{
string temp = leftSide.substr(index, (index+1));//add THIS capital and next lowercase
elementSymbol.push_back(temp); // add temp to vector
temp.clear(); //used to try and fix problem initially
}
else if (UPPER_LETTER && !NEXT_LOWER_LETTER) //used to try and prevent number from getting in
{
string temp = leftSide.substr(index, index);
elementSymbol.push_back(temp);
}
}
else if (isdigit(leftSide[index])) // if it's a number
num++;
}
[EDIT] When I entered in only ASDF, *** ***S ***DF ***F was the output.
string temp = leftSide.substr(index, (index+1));
substr takes the first index and then a length, rather than first and last indices. You want substr(index, 2). Since in your example index is 0 you're doing: substr(index, 1) which creates a string of length 1, which is "C".
string temp = leftSide.substr(index, index);
Since index is 0 this is substr(index, 0), which creates a string of length 0, that is, an empty string.
When you're processing parts of the string with a higher index, such as Fe in "CuFe3" the value you pass in as the length parameter is higher and so you're creating strings that are longer. F is at index 2 and you call substr(index, 3), which creates the string "Fe3".
Also the standard library usually uses half open ranges, so even if substr took two indices (which, again, it doesn't) you would do substr(index, index+2) to get a two character string.
bool NEXT_LOWER_LETTER = islower(leftSide[index+1]);
You might want to check that index+1 is a valid index. If you don't want to do that manually you might at least switch to using the bounds checked function at() instead of operator[].
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Our profeesser assigned this project but Im at a loss of how to do it. Normally I would figure it out on my own but Ive got a massive English paper due on the same day and I have to finish that also this weekend. The program is due on 11/12/13 but can be turned in by 11/19/13 with a 20% penalty to grade.
Write and test a C++ program to complete the following project:
Generate a table of numbers for use in a math problem.
Ask the user for three numbers:
The first number represents how many values are to be in the table (1
to 25).
The second number represents the first value in the table. (-1000 to
+1000)
The third number represents the increment between successive values
in the table. (1 to 20)
Iterate through the selected values, generating and saving the following derived values from each value in the iteration:
Square
Square Root (only if the value is positive or zero, display “N/A” for
all other values)
Cube
Cube Root (only if the value is positive or zero, display “N/A” for
all other values)
Whether the number is even or odd
Whether the number is prime or not (Prepare a user-defined function
based on the logic in Assignment 5).
Save the results of the calculations in a set of arrays, one array for each calculated value.
After all values are calculated and saved, display the values in a tabular form with one column for each calculated value and a row for each set of values (corresponding to the first value read from the user).
Note that for each negative value in the first column, display “N/A” in the columns for square root and cube root.
Display “Even” or “Odd” for each number’s even/odd status. Display “True” or “False” for the number’s prime-ness.
Repeat this process until the user enters a count of zero for the number of values in the table.
Bonus: Read a series of three-number sets from a data file named triples.txt and create a table of numbers corresponding to each three-number set. Save the resulting tables of numbers to a single text file named numbers.csv in comma-separated-value format.
Heres' what i have so far:
// TABLEation.cpp : builds a table based on user input.
//
using namespace std;
double square, squareroot,cube,cuberoot;
int initialValue,display,increment;
string even,prime;
const int SIZE=25;
int Value[SIZE];
bool isEven( int integer )
{
if ( integer % 2== 0 )
return true;
else
return false;
}
bool isPrime(int testValue) {
int divisor=0, remainder=0;
if (testValue<2) return false;
for(divisor=2; divisor<=sqrt(testValue);divisor++){
if((testValue % divisor)==0) return false;
}
return true;
}
int _tmain()
{
do{
begining:
cout<<"Enter how many values to show (1-25)."<<endl;
cin>>display;
if((display>0) && (display<=25)){
cout<<"Enter an initial Value (-1000 to 1000)."<<endl;
cin>>initialValue;
}
else{
cout<<"ERRROR! INVALID INPUT!TRY AGAIN"<<endl;
goto begining;
}
if ((initialValue>= -1000) && (initialValue<=1000)){
cout<<"Enter a number to increment by (1-20)"<<endl;
cin>>increment;
}
else{
cout<<"ERRROR! INVALID INPUT!TRY AGAIN"<<endl;
goto begining;
}
}
system("pause");
return 0;
}
where should I go from here?
Since there is no question above I am guessing you want someone to either give you the answer, or give you hints towards the right direction. I am going to pretend you are after the latter. The problem is fairly straightforward.
Generate a table of numbers for use in a math problem.
Ask the user for three numbers:
The first number represents how many values are to be in the table (1 to 25).
he second number represents the first value in the table. (-1000 to +1000)
The third number represents the increment between successive values in the table. (1 to 20)
Since below we see that you are to ask these questions in a loop until the first answer is 0 you could build a function "bool get_input(int &num_values, int &start_num, int &increment)" This function will return false if the user puts in a value that is not within the ranges and true otherwise. Now call this function in a while loop where you exit if the num_values is 0.
Iterate through the selected values, generating and saving the following derived values from each value in the iteration:
This is a for loop where i = start_num and at each iteration you increase i+=increment
for each iteration of your for loop you should be calling the following six functions:
Square
int square(int i) which returns the square of the value.
Square Root (only if the value is positive or zero, display “N/A” for all other values)
bool extract_square_root(int i, float &square_root) which returns false if the value is negative, otherwise it puts the square root into the reference variable.
Cube
int cube(int i) which returns the cube of the value.
Cube Root (only if the value is positive or zero, display “N/A” for all other values)
bool extract_cube_root(int i, float &cube_root) -- as above
Whether the number is even or odd
bool even_or_odd(int i) which returns true if the value is even and false otherwise.
Whether the number is prime or not (Prepare a user-defined function based on the logic in Assignment 5)
bool prime(int i) which returns true if the value is prime. (use assignment 5).
Save the results of the calculations in a set of arrays, one array for each calculated value.
for each result store it in an array (square_root_array, cube_root_array, etc.)
After all values are calculated and saved, display the values in a tabular form with one column for each calculated value and a row for each set of values (corresponding to the first value read from the user).
call a function void display_values(float square_root_array[], ...) which iterates through each of your arrays and prints the values according to the rules listed below:
Note that for each negative value in the first column, display “N/A” in the columns for square root and cube root.
Display “Even” or “Odd” for each number’s even/odd status.
Display “True” or “False” for the number’s prime-ness.
The next part is already handled by our while loop.
Repeat this process until the user enters a count of zero for the number of values in the table.
I will leave the Bonus for you to figure out.
Bonus: Read a series of three-number sets from a data file named triples.txt and create a table of numbers corresponding to each three-number set. Save the resulting tables of numbers to a single text file named numbers.csv in comma-separated-value format.
Good luck, and get used to working all nighters if you plan on taking a lot of CS. It's par for the course.
P.S. If you follow these directions and look up how to do each step where you are unsure, you could get this project off of your plate in a couple hours.
In my c++ class, we got assigned pairs. Normally I can come up with an effective algorithm quite easily, this time I cannot figure out how to do this to save my life.
What I am looking for is someone to explain an algorithm (or just give me tips on what would work) in order to get this done. I'm still at the planning stage and want to get this code done on my own in order to learn. I just need a little help to get there.
We have to create histograms based on a 4 or 5 integer input. It is supposed to look something like this:
Calling histo(5, 4, 6, 2) should produce output that appears like:
*
* *
* * *
* * *
* * * *
* * * *
-------
A B C D
The formatting to this is just killing me. What makes it worse is that we cannot use any type of arrays or "advanced" sorting systems using other libraries.
At first I thought I could arrange the values from highest to lowest order. But then I realized I did not know how to do this without using the sort function and I was not sure how to go on from there.
Kudos for anyone who could help me get started on this assignment. :)
Try something along the lines of this:
Determine the largest number in the histogram
Using a loop like this to construct the histogram:
for(int i = largest; i >= 1; i--)
Inside the body of the loop, do steps 3 to 5 inclusive
If i <= value_of_column_a then print a *, otherwise print a space
Repeat step 3 for each column (or write a loop...)
Print a newline character
Print the horizontal line using -
Print the column labels
Maybe i'm mistaken on your q, but if you know how many items are in each column, it should be pretty easy to print them like your example:
Step 1: Find the Max of the numbers, store in variable, assign to column.
Step 2: Print spaces until you get to column with the max. Print star. Print remaining stars / spaces. Add a \n character.
Step 3: Find next max. Print stars in columns where the max is >= the max, otherwise print a space. Add newline. at end.
Step 4: Repeat step 3 (until stop condition below)
when you've printed the # of stars equal to the largest max, you've printed all of them.
Step 5: add the -------- line, and a \n
Step 6: add row headers and a \n
If I understood the problem correctly I think the problem can be solved like this:
a= <array of the numbers entered>
T=<number of numbers entered> = length(a) //This variable is used to
//determine if we have finished
//and it will change its value
Alph={A,B,C,D,E,F,G,..., Z} //A constant array containing the alphabet
//We will use it to print the bottom row
for (i=1 to T) {print Alph[i]+" "}; //Prints the letters (plus space),
//one for each number entered
for (i=1 to T) {print "--"}; //Prints the two dashes per letter above
//the letters, one for each
while (T!=0) do {
for (i=1 to N) do {
if (a[i]>0) {print "*"; a[i]--;} else {print " "; T--;};
};
if (T!=0) {T=N};
}
What this does is, for each non-zero entered number, it will print a * and then decrease the number entered. When one of the numbers becomes zero it stops putting *s for its column. When all numbers have become zero (notice that this will occur when the value of T comes out of the for as zero. This is what the variable T is for) then it stops.
I think the problem wasn't really about histograms. Notice it also doesn't require sorting or even knowing the