I have a 2-D array of gems, all the gems have been given random color. Now i want to detect if three or more consecutive gems in a row or column has the same color. If so i want to do some action with those gems.
Gem gems[10][10];
for(int i=0;i<10;++i){
for(int j=0;j<10;++j){
gems[i][j].setColor(GetRandInRange(0,6));
}
}
bool detectMatch(){
for(int i=0;i<10;++i){
for(int j=0;j<10;++j){
// Code to detect three or more consecutive gems with same color
// Give some special color to the matched gems
}
}
Here is how i tried but it doesn't work
bool GameBoard::findMatch(){
for(int i=0;i<10;++i){
int count=0;
for(int j=0;j<10;++j){
if(j!=0){
if(gems[i][j].getColor()==gems[i][j-1].getColor()){ //Color same with previous one
int a=i, b=j;
while(gems[a][b].getColor()==gems[i][j].getColor() && (a<10 && b<10)){ // Check till the color does not match
count++;
a++;
b++;
}
if(count>=3){ //If 3 or more have matched
for(int a=i, b=j, c=0;c<count;++c){
gems[a][b].setColor(0);
}
return true;
}
}
}
}
}
return false;
}
if you can help me with this code please
Here's how I'd go about it. You need to do two scans. First, you need to scan for runs in one direction, then the other. It's much simpler than trying to loop through once.
I first check for horizontal runs, exiting as soon as one longer than 2 is found. Same with the vertical ones. Your function has a bool signature, so I've assumed you'll use another function to determine the location of the run - you could easily return a struct that held the position, direction and length from the findMatch method.
"use strict";
window.addEventListener('load', onLoaded, false);
var gems;
function onLoaded(evt) {
// create and initialize the array
gems = new Array();
for (var row = 0; row < 10; row++) {
let curRow = new Array();
for (var col = 0; col < 10; col++) {
let curCell = new Gem();
curCell.setColor(GetRandInRange(0, 6));
curRow.push(curCell);
}
gems.push(curRow);
}
// display it for the user
displayGems();
// check if there's 3 or more in a vertical or horizontal line.
console.log(hasMatch());
}
class Gem {
setColor(colIndex) {
this.color = colIndex;
}
getColor() {
return this.color;
}
};
function displayGems() {
var str = '';
for (var row = 0; row < 10; row++) {
if (row != 0)
str += "\n";
var dat = gems[row];
dat.forEach((gem, idx) => {
if (idx != 0)
str += ', ';
str += gem.getColor();
});
}
console.log(str);
}
function GetRandInRange(lower, upper) {
return ((Math.random() * (upper - lower)) + lower + 0.5) >> 0;
}
function hasMatch() {
let matchFound = 0;
// scan #1 - horizontally on each row
for (var row = 0; row < 10; row++) {
let last = undefined;
let runLength = 0;
for (var col = 0; col < 10; col++) {
let cur = gems[row][col].getColor();
if (cur == last) {
runLength++
if (runLength > 2) {
console.log(`horiz - ${row+1}`);
return true;
}
} else {
runLength = 0;
last = cur;
}
}
}
for (var col = 0; col < 10; col++) {
let last = undefined;
let runLength = 1;
for (var row = 0; row < 10; row++) {
let cur = gems[row][col].getColor();
if (cur == last) {
runLength++;
if (runLength > 2) {
console.log(`vert - ${col+1}`);
return true;
}
} else {
runLength = 1;
last = cur;
}
}
}
return false;
}
Related
How can I read rows by group using Aspose?
example
See the following sample code using Aspose.Cells for your reference:
e.g.
Sample code:
//Loading the file
Workbook book = new Workbook("e:\\test2\\Bk_readgrouped.xlsx");
//Get the first worksheet in the workbook
Worksheet sheet = book.Worksheets[0];
int maxRow = sheet.Cells.MaxDataRow;
int maxCol = sheet.Cells.MaxDataColumn;
int chk = 0;
bool pname = false;
Console.WriteLine("Retrieving each group's data");
for (int i = 0; i <= maxRow; i++)
{
int rowOutlineLevel = sheet.Cells.GetGroupedRowOutlineLevel(i);
if (rowOutlineLevel > 0)
{
pname = true;
if (pname== true & chk != rowOutlineLevel)
{
Console.WriteLine("\n");
Console.WriteLine("Group:" + rowOutlineLevel);
pname = false;
chk = rowOutlineLevel;
}
for (int j = 0; j <= maxCol; j++)
{
Console.Write(sheet.Cells[i, j].StringValue + "\t");
}
Console.WriteLine();
}
}
Hope, this helps a bit.
PS. I am working as Support developer/ Evangelist at Aspose.
This works for me:
public virtual void ProcessExcelSheetTree (Worksheet Excelsheet, int current_level)
{
int current_row = 1;
int maxRow = Excelsheet.Cells.MaxDataRow;
int firstGroupIndex = 0;
while(Excelsheet.Cells[current_row, 0].StringValue != "")
{
var currentRow = Excelsheet.Cells.Rows[current_row];
if(currentRow.GroupLevel == current_level)
{
string targetName = Excelsheet.Cells[current_row, 0].StringValue;
Console.WriteLine(targetName);
firstGroupIndex = currentRow.Index;
for (int i = firstGroupIndex + 1; i <= maxRow; i++)
{
if(Excelsheet.Cells.Rows[i].GroupLevel > current_level)
{
string subTargetName = Excelsheet.Cells[i, 0].StringValue;
Console.WriteLine(" - " + subTargetName);
}
else
{
break;
}
}
}
current_row++;
}
}
I want to compare two arrays. One of them is a subset of the other one. I want my function to return the minimum and equal gap between the numbers of the first subset array in the other array.
For example if I have
arr1 = 2,1,4,2,8,3
sub= 1,2,3
I want my function to return 1 because the mimimum gap between all this numbers are 1.
arr1 = 2,1,5,2,1,2,3
sub= 1,2,3
I want my function to return 0 because the mimimum gap between 1,2,3 in arr1 is 0
Here is the code I am trying to do: My code always return 0 can you help me understand why, and how can I solve this.
int gap(int* arr, int* sub, int sizeArr, int sizeSub)
{
int index = 0; int gap = 0; bool flag = true;
int i = -1;
for (int jump = 1; jump < sizeArr / sizeSub; jump++)
{
index = 0;
for (i = i +1; i < sizeArr; i++)
{
if (sub[index] == arr[i])
{
for (int j = i + jump, index = 1; j < sizeArr; j = j + jump, index++)
{
if (arr[j] != sub[index]) { flag = false; break; }
else if (arr[j] == sub[index] && index == sizeSub) { flag = true; break; }
}
}
if (!flag) { break; }
else { gap = jump; break; }
}
}
return gap;
}
You initially took gap equally 0 but i think more suit to not store gap
and start iterate jump from 0. And return jump immediately after you found that it is suit.
Also i think that store index in such manner as you it is bad idea, because you code return wrong answer on
int a[] = { 2,1,4,4,2,8,5,3 };
int s[] = { 1,2,3 };
I think you should declare variable as soon as possible, otherwise there will be undesirable side effects.
So you code can be rewritten as
int gap(int *arr, int *sub, int sizeArr, int sizeSub)
{
for (int jump = 0; 1 + (jump + 1) * (sizeSub - 1) <= sizeArr; jump++) {
for (int start_index = 0; start_index + (jump + 1) * (sizeSub - 1) < sizeArr; start_index++) {
bool flag = true;
for (int index = 0; index < sizeSub; ++index) {
if (arr[start_index + index * (jump + 1)] != sub[index]) {
flag = false;
break;
}
}
if (flag) {
return jump;
}
}
}
return -1; //or some value that indicate that there is no answer
}
My solution is correct and passes all test cases, but my solution is very slow (faster than 7% of C++ solutions).
Question:
Given an m x n board of characters and a list of strings words, return all words on the board.
Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
For example:
Input: board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
Output: ["eat","oath"]
By the way, I don't have Leetcode premium and looked at the discussion. I see that other people are using recursion. I am using a stack, but this shouldn't really be a problem. Does anyone see any performance issues with my code? The complexity should be O(n^2*3^n)
class Solution {
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
vector<string> ret;
Trie* root = new Trie();
for (const auto &i:words) {
root->insert(i);
}
Trie* cnode = root;
int numRow = board.size();
int numCol = board[0].size();
vector<int> temp(numCol, 0);
vector<vector<int>> visited(numRow, temp);
for (int i = 0; i < numRow; ++i) {
for (int j = 0; j < numCol; ++j) {
stack<pair<int, int>> searcher;
searcher.push(make_pair(i,j));
while (!searcher.empty()) {
int row = searcher.top().first;
int col = searcher.top().second;
int cur = board[row][col] - 97;
if (visited[row][col]) {
cnode = cnode->parent;
visited[row][col] = 0;
searcher.pop();
} else if (cnode->child[cur] == nullptr) {
searcher.pop();
visited[row][col] = 0;
} else {
visited[row][col] = 1;
cnode = cnode->child[cur];
if (cnode->contain != "") {
ret.push_back(cnode->contain);
cnode->contain = "";
}
if (row + 1 < numRow && !visited[row + 1][col]) {
searcher.push(make_pair(row+1, col));
}
if (row - 1 >= 0 && !visited[row-1][col]) {
searcher.push(make_pair(row-1, col));
}
if (col + 1 < numCol && !visited[row][col+1]) {
searcher.push(make_pair(row, col+1));
}
if (col - 1 >= 0 && !visited[row][col-1]) {
searcher.push(make_pair(row, col-1));
}
}
}
}
}
return ret;
}
class Trie {
public:
vector<Trie*> child;
Trie* parent;
string contain;
Trie() {
child = vector<Trie*>(26, nullptr);
contain = "";
parent = nullptr;
}
void insert(string word) {
Trie* root = this;
for (int i = 0; i < word.size(); ++i) {
int loc = word[i] - 97;
if (root->child[loc] == nullptr) {
root->child[loc] = new Trie();
root->child[loc]->parent = root;
}
root = root->child[loc];
}
root->contain = word;
}
};
};
I am developing a wordsearch generator to learn c++ better and I am stuck on preventing non-overlapping words from overlapping, such as a side-to-side word writing over a letter in a top-down word. Here is the code snippet:
else if (random_choice == 1 && random_word.size() <= 10-j && words_vector.size() != 0) {
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i][j+x] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
j += 1;
}
j -= 1;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
What I have done was create a two dimensional array [10][11] filled with the 0 (zero) character so when I iterate through it all spaces are filled with 0 except for the 11th space in each line with a newline character to make a 10X10 grid. In my else if loop, the first part already has a word chosen and it tests if the word will fit in its proper space by checking if a 0 is present. If it runs into a non-zero character (such as if it runs into a letter from a top-down or diagonal word) the inner loop terminates, sets the boolean flag, and inputs a 1 (or any random letter) instead of the whole word. What happens is that the whole word is inserted anyways and overwrites one letter from the top down word. What am I doing wrong? Here is the rest of the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
srand(time(NULL));
const char* const a_to_z = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
int random_char;
char wordsearch [10][11] = {0};
bool flag;
string words_array[] = {"CAT", "HELLO", "GOODBYE", "DOG", "BAT", "NEW", "SAY", "MAY", "DAY", "HAY"};
vector<string> words_vector (words_array, words_array + sizeof(words_array) / sizeof(string));
string words_found_array[] = {};
vector<string> words_found_vector (words_found_array, words_found_array + sizeof(words_found_array) / sizeof(string));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 11; j++) {
int random_choice = rand() % 5;
int random_word_number = rand() % words_vector.size();
string random_word = words_vector[random_word_number];
if (j == 10) {
wordsearch[i][j] = '\n';
}
else if (random_choice == 1 && random_word.size() <= 10-j && words_vector.size() != 0) {
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i][j+x] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
j += 1;
}
j -= 1;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
else if (random_choice == 2 && random_word.size() <= 10-i && words_vector.size() != 0) {
int temp_i = i;
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i+x][j] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
i += 1;
}
i = temp_i;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
else {
int random_char = rand() % 26 + 0;
wordsearch[i][j] = a_to_z[random_char];
}
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 11; j++) {
cout<<wordsearch[i][j];
}
}
cout<<"Your words are:"<<endl;
for (int x = 0; x < words_found_vector.size(); x++) {
cout<<words_found_vector[x]<<endl;
}
}
One more thing:
//words_vector.erase(words_vector.begin()+random_word_number);
crashes my program. I think it is a scoping issue with this:
int random_choice = rand() % 5;
int random_word_number = rand() % words_vector.size();
string random_word = words_vector[random_word_number];
What I want to do is eventually have the user give me a list of words they want to search for and this function chooses some of them and presents it to the user when playing the game. This not functioning correctly also causes duplicates to appear in the crossword and words-to-find-list.
Thank you for your help!
You have this error twice in your code:
if (flag = true)
That is not a condition, it's an assignment. It assigns true to flag, and the if-block will always execute. You need to make it a comparison condition by using ==
if (flag == true)
A more common way to write that in C++ would be just
if (flag)
I am making a Tic Tac Toe game and i created a function that inserts X or O into my array. I have run into one problem with my design. I call the function to make a move for X, but when it is the next players turn how do i make it call for O?
Is there a way after i put makeMove() i can just call somehow it to take in O turn instead of X. Because as you can see if i do X it will just always ask for X and not O. How can i make it choose to pull in X or O turn.
The problem is i need to only have one function that makes moves.
int main()
{
while(SOME CONDITION HERE)
{
printBoard();
cout << "Player X please choose a position: ";
makeMove('X');
cout << "Player O please choose a position: ";
makeMove('O');
}
}
int makeMove(char marker)
{
int choosePosition = 0;
cin >> choosePosition;
ticTacBoard[choosePosition - 1] = marker;
}
Start with this:
int main()
{
while(SOME CONDITION HERE)
{
printBoard();
cout << "Player X please choose a position: ";
makeMove('X');
cout << "Player O please choose a position: ";
makeMove('O');
}
}
int makeMove(char marker)
{
int choosePosition = 0;
cin >> choosePosition;
ticTacBoard[choosePosition - 1] = marker;
}
Note that you're going to want to change the SOME CONDITION HERE part, but you could quickly replace it by 1 and get the same behavior of your current script (actually, a bit better).
But you'll eventually want to put something there that makes sense -- something that will tell the program to stop prompting the players for positions and, say, declare a winner.
The following is just a more streamlined way of doing the same thing:
int main()
{
while(SOME CONDITION HERE)
{
printBoard();
makeMove('X');
makeMove('O');
}
}
int makeMove(char marker)
{
cout << "Player " << marker << " please choose a position: ";
int choosePosition = 0;
cin >> choosePosition;
ticTacBoard[choosePosition - 1] = marker;
return 0;
}
Note the added return 0 -- if you don't want to return something, you should just make makeMove return void so as not to be confusing.
You might try using an argument:
int makeMove(char player);
makeMove('O');
makeMove('X');
First of all, don't call main() recursively. Use a loop instead.
Secondly, use a variable (such as player below) to indicate whose turn it is.
int main()
{
char player = 'X';
while (/* game not finished */) {
printBoard();
makeMove(player);
player = (player == 'X') ? 'O' : 'X';
}
}
void makeMove(char player)
{
cout << "Player " << player << " please choose a position: ";
int choosePosition = 0;
cin >> choosePosition;
ticTacBoard[choosePosition - 1] = player;
}
Something like this may work... just be sure to use a loop for the moves.
char player = 'X';
while(...) {
cout << "choose position...";
makeMove(player);
if(player == 'X')
player = 'O';
else
player = 'X';
...
}
//in make move:
int makeMove(char player) {
int choosePosition = 0;
cin >> choosePosition;
ticTacBoard[choosePosition - 1] = player;
}
http://scripts.franciscocharrua.com/javascript/tic-tac-toe/
I added this to my website a few months ago. I admit it may be a bit complex, and in JavaScript, but it may be of some help.
JS:
function tic_tac_toe(blank_token, player_tokens, artificial_intelligence)
{
this.board = [[blank_token, blank_token, blank_token],
[blank_token, blank_token, blank_token],
[blank_token, blank_token, blank_token]];
this.blank_token = blank_token;
this.player_tokens = player_tokens;
this.display_choice = function() {};
this.declare_human_win = function() {};
this.declare_computer_win = function() {};
this.declare_tie = function() {};
this.artificial_intelligence = artificial_intelligence;
this.start =
function()
{
//Randomly choose a token for the human player.
var human_token_index = Math.floor(Math.random() * this.player_tokens.length);
this.human_player = this.player_tokens[human_token_index];
//Place the chosen token at the end of the array.
this.player_tokens[human_token_index] = this.player_tokens[this.player_tokens.length - 1];
this.player_tokens[this.player_tokens.length - 1] = this.human_player;
//Randomly choose a different token for the computer player.
var computer_token_index = Math.floor(Math.random() * (this.player_tokens.length - 1));
this.computer_player = this.player_tokens[computer_token_index];
//Clear the board.
for(var row = 0; row < 3; row++)
for(var collumn = 0; collumn < 3; collumn++)
{
this.place(this.blank_token, row, collumn);
}
if(Math.random() < 0.5)
{
this.turn = this.computer_player;
this.computer_turn();
}
else
{
this.turn = this.human_player;
}
};
//Returns the token of the winning player.
//If no one has won yet or the game is tied, returns the blank token.
//Used in combination with blank_token_count() to determine if the game is tied.
this.winner =
function()
{
var winner = this.blank_token;
//Check for 3 consecutive horisontal tokens.
for(var row = 0; row < 3; row++)
{
winner = this.board[row][0];
for(var collumn = 1; collumn < 3; collumn++)
{
if(this.board[row][collumn] != winner)
{
winner = this.blank_token;
}
}
if(winner != this.blank_token)
{
return(winner);
}
}
//Check for 3 consecutive vertical tokens.
for(var collumn = 0; collumn < 3; collumn++)
{
winner = this.board[0][collumn];
for(var row = 1; row < 3; row++)
{
if(this.board[row][collumn] != winner)
{
winner = this.blank_token;
}
}
if(winner != this.blank_token)
{
return(winner);
}
}
//Check for 3 consecutive diagonal tokens.
winner = this.board[0][0];
for(var row = 1; row < 3; row++)
{
if(this.board[row][row] != winner)
{
winner = this.blank_token;
}
}
if(winner != this.blank_token)
{
return(winner);
}
winner = this.board[0][2];
for(var row = 1; row < 3; row++)
{
if(this.board[row][2 - row] != winner)
{
winner = this.blank_token;
}
}
if(winner != this.blank_token)
{
return(winner);
}
return(winner);
};
this.blank_token_count =
function()
{
var blank_token_count = 0;
for(var row = 0; row < 3; row++)
for(var collumn = 0; collumn < 3; collumn++)
{
if(this.board[row][collumn] == this.blank_token)
{
blank_token_count++;
}
}
return(blank_token_count);
};
this.computer_turn =
function()
{
//Lets the computer take its turn if the game is not over.
if(this.turn != this.blank_token)
{
this.turn = this.computer_player;
var computer_move = this.artificial_intelligence();
this.place(this.computer_player, computer_move.row, computer_move.collumn);
}
};
this.human_turn =
function(row, collumn)
{
this.place(this.human_player, row, collumn);
this.computer_turn();
}
this.place =
function(token, row, collumn)
{
if(row < 3 && collumn < 3 &&
((this.turn == token && this.board[row][collumn] == this.blank_token) || token == this.blank_token))
{
this.board[row][collumn] = token;
this.display_choice(token, row, collumn)
//Finishes the game in case a of a win or a tie.
//When the board is not being reset.
if(token != this.blank_token)
{
var winner_token = this.winner();
if(winner_token == this.human_player)
{
this.declare_human_win();
this.turn = this.blank_token;
}
if(winner_token == this.computer_player)
{
this.declare_computer_win();
this.turn = this.blank_token;
}
if(winner_token == this.blank_token && this.blank_token_count() == 0)
{
this.declare_tie();
this.turn = this.blank_token;
}
//Gives the human player a turn, if the game is not over.
if(this.turn == this.computer_player)
{
this.turn = this.human_player
}
}
}
};
}