- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个由单元格组成的 2D 网格游戏,玩家必须在其中放置代币并尝试包含(包围)对手的代币。现在每个单元格可以有 3 种状态:空、包含红色 token 或包含蓝色 token 。
所有可以形成“路径”的单元格都在一个列表中,沿着该路径我可以绘制经过单元格中心的线(多边形)。还有一个包含的标记列表,被圈起来的标记,
现在我想找到一种方法来“无效”包围的标记,以便路径计算可以忽略它
请参阅下面的示例:
下面的所有代码都来自路径类:
class Path extends Stack<int[]>{
private Token[][] grid;
//a path shorter than min can not surround any cell
private static final int MIN_PATH_LEGTH = 3;
//a collection of cells that has been tested
private ArrayList<int[]>checked;
//represents the cell where the search starts from
int[] origin;
//represents the token of the origin
Token originToken;
private int rows;
private int cols;
//represents the path bounds: min/max row/col in path
private int minPathRow, maxPathRow, minPathCol, maxPathCol;
Path(Token[][] grid){
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
}
//search for a path
boolean findPath(int[] origin) {
this.origin = origin;
int row = origin[0] , col = origin[1];
//represents the token of the origin
originToken = grid[row][col];
//initialize list of checked items
checked = new CellsList();
boolean found = findPath(row, col);
if(found) {
printPath();
} else {
System.out.println("No path found");
}
return found;
}
//recursive method to find path. a cell is represented by its row, col
//returns true when path was found
private boolean findPath(int row, int col) {
//check if cell has the same token as origin
if(grid[row][col] != originToken) {
return false;
}
int[] cell = new int[] {row, col};
//check if this cell was tested before to avoid checking again
if(checked.contains(cell)) {
return false;
}
//get cells neighbors
CellsList neighbors = getNeighbors(row, col);
//check if solution found. If path size > min and cell
//neighbors contain the origin it means that path was found
if((size() >= MIN_PATH_LEGTH) && neighbors.contains(origin) ) {
add(cell);
return true;
}
//add cell to checked
checked.add(cell);
//add cell to path
add(cell);
//if path was not found check cell neighbors
for(int[] neighbor : neighbors ) {
boolean found = findPath(neighbor[0],neighbor[1]);
if(found) {
return true;
}
}
//path not found
pop(); //remove last element from stack
return false;
}
//use for testing
private void printPath() {
System.out.print("Path : " );
for(int[] cell : this) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
List<int[]> containedCells = getContainedWithin();
System.out.print(containedCells.size() +" cell contained : " );
for(int[] cell : containedCells) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
}
CellsList getPath() {
CellsList cl = new CellsList();
cl.addAll(this);
return cl;
}
}
下面的代码查找单元格的邻居 (path.java):
//return a list of all neighbors of cell row, col
private CellsList getNeighbors(int row, int col) {
CellsList neighbors = new CellsList();
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(isWithinGrid (rowNum, colNum ) ) {
neighbors.add( new int[] {rowNum, colNum});
}
}
}
}
return neighbors;
}
private boolean isWithinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0) ) {
return false;
}
if((colNum >= cols) || (rowNum >= rows)) {
return false;
}
return true;
}
}
下面的代码通过路径查找所有有界单元格(所有包含或包围的标记),并且它们的标记具有与路径相反的颜色:
List<int[]> getContainedWithin() {
//find path max and min X values, max and min Y values
minPathRow = grid[0].length; //set min to the largest possible value
maxPathCol = grid.length;
maxPathRow = 0; //set max to the largest possible value
maxPathCol = 0;
//find the actual min max x y values of the path
for (int[] cell : this) {
minPathRow = Math.min(minPathRow, cell[0]);
minPathCol = Math.min(minPathCol, cell[1]);
maxPathRow = Math.max(maxPathRow, cell[0]);
maxPathCol = Math.max(maxPathCol, cell[1]);
}
List<int[]> block = new ArrayList<>(25);
int[] cell = get(0);//get an arbitrary cell in the path
Token pathToken = grid[cell[0]][cell[1]]; //keep a reference to its token
//iterate over all cells within path x, y limits
for (int col = minPathCol; col < (maxPathCol); col++) {
for (int row = minPathRow; row < (maxPathRow); row++) {
//check cell color
Token token = grid[row][col];
if ((token == pathToken) || (token == Token.VIDE)) {
continue;
}
if (isWithinLoop(row,col)) {
block.add(new int[] {row, col});
}
}
}
return block;
}
//check if row, col represent a cell within path by checking if it has a
//path-cell to its left, right, top and bottom
private boolean isWithinLoop(int row, int col) {
if( isPathCellOnLeft(row, col)
&&
isPathCellOnRight(row, col)
&&
isPathCellOnTop(row, col)
&&
isPathCellOnBottom(row, col)
) {
return true;
}
return false;
}
}
如果您需要更多元素,请现在告诉我,我将更新必要的元素。
最佳答案
这个要求意味着之前的路径会影响当前的路径计算。
可以通过多种方式实现。在当前的程序结构中,最简单的方法可能是在所有路径中添加包含单元格的静态集合。
请参阅 allContainedWithin
及其在代码中的使用方式。
另请注意,我将 getContainedWithin()
重构为 getter,并将其功能移至新方法 findContainedWithin()
。所有更改都不会影响其他类。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
//a stack representing cells in the path
//each cell represented by [row,col]
class Path extends Stack<int[]>{
private Token[][] grid;
//a path shorter than min can not surround any cell
private static final int MIN_PATH_LEGTH = 3;
//a collection of cells that has been tested
private ArrayList<int[]>checked;
//represents the cell where the search starts from
int[] origin;
//represents the token of the origin
Token originToken;
private int rows;
private int cols;
//represents the path bounds: min/max row/col in path
private int minPathRow, maxPathRow, minPathCol, maxPathCol;
//a collection of all cells that are bounded by the path
//and their token is of the opposite color of the path
private List<int[]> containedWithin;
//a STATIC collection that holds all containedWithin cells, of
//current and previous paths
private static CellsList allContainedWithin = new CellsList();
Path(Token[][] grid){
this.grid = grid;
rows = grid.length;
cols = grid[0].length;
}
//search for a path
boolean findPath(int[] origin) {
this.origin = origin;
int row = origin[0] , col = origin[1];
//represents the token of the origin
originToken = grid[row][col];
//initialize list of checked items
checked = new CellsList();
boolean found = findPath(row, col);
if(found) {
//find bounded cells
findContainedWithin();
//update the collection all
allContainedWithin.addAll(containedWithin);
printPath();
} else {
System.out.println("No path found");
}
return found;
}
//recursive method to find path. a cell is represented by its row, col
//returns true when path was found
private boolean findPath(int row, int col) {
//check if cell has the same token as origin
if(grid[row][col] != originToken) {
return false;
}
int[] cell = new int[] {row, col};
//check if this cell was tested before to avoid checking again
if(checked.contains(cell)) {
return false;
}
//check if this cell was contained in previously calculated paths
if(allContainedWithin.contains(cell)) {
return false;
}
//get cells neighbors
CellsList neighbors = getNeighbors(row, col);
//check if solution found. If path size > min and cell
//neighbors contain the origin it means that path was found
if((size() >= MIN_PATH_LEGTH) && neighbors.contains(origin) ) {
add(cell);
return true;
}
//add cell to checked
checked.add(cell);
//add cell to path
add(cell);
//if path was not found check cell neighbors
for(int[] neighbor : neighbors ) {
boolean found = findPath(neighbor[0],neighbor[1]);
if(found) {
return true;
}
}
//path not found
pop(); //remove last element from stack
return false;
}
//return a list of all neighbors of cell row, col
private CellsList getNeighbors(int row, int col) {
CellsList neighbors = new CellsList();
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(isWithinGrid (rowNum, colNum ) ) {
neighbors.add( new int[] {rowNum, colNum});
}
}
}
}
return neighbors;
}
private boolean isWithinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0) ) {
return false;
}
if((colNum >= cols) || (rowNum >= rows)) {
return false;
}
return true;
}
//use for testing
private void printPath() {
System.out.print("Path : " );
for(int[] cell : this) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
List<int[]> containedCells = getContainedWithin();
System.out.print(containedCells.size()+" cell contained : " );
for(int[] cell : containedCells) {
System.out.print(Arrays.toString(cell));
}
System.out.println("");
}
CellsList getPath() {
CellsList cl = new CellsList();
cl.addAll(this);
return cl;
}
//finds all cells that are bounded by the path
//and their token is of the opposite color of the path
private void findContainedWithin() {
containedWithin = new ArrayList<>();
//find path max and min X values, max and min Y values
minPathRow = grid[0].length; //set min to the largest possible value
maxPathCol = grid.length;
maxPathRow = 0; //set max to the largest possible value
maxPathCol = 0;
//find the actual min max x y values of the path
for (int[] cell : this) {
minPathRow = Math.min(minPathRow, cell[0]);
minPathCol = Math.min(minPathCol, cell[1]);
maxPathRow = Math.max(maxPathRow, cell[0]);
maxPathCol = Math.max(maxPathCol, cell[1]);
}
//todo remove after testing
System.out.println("x range: "+minPathRow + "-"
+ maxPathRow + " y range: " + minPathCol + "-" + maxPathCol);
int[] cell = get(0);//get an arbitrary cell in the path
Token pathToken = grid[cell[0]][cell[1]]; //keep a reference to its token
//iterate over all cells within path x, y limits
for (int col = minPathCol; col < (maxPathCol); col++) {
for (int row = minPathRow; row < (maxPathRow); row++) {
//check cell color
Token token = grid[row][col];
if ((token == pathToken) || (token == Token.VIDE)) {
continue;
}
if (isWithinLoop(row,col)) {
containedWithin.add(new int[] {row, col});
}
}
}
}
//returns a collection of all cells that are bounded by the path
//and their token is of the opposite color of the path
List<int[]> getContainedWithin() {
return containedWithin;
}
//check if row, col represent a cell with in path by checking if it has a
//path-cell to its left, right, top and bottom
private boolean isWithinLoop(int row, int col) {
if( isPathCellOnLeft(row, col)
&&
isPathCellOnRight(row, col)
&&
isPathCellOnTop(row, col)
&&
isPathCellOnBottom(row, col)
) {
return true;
}
return false;
}
private boolean isPathCellOnLeft(int cellRow, int cellCol) {
for ( int col = minPathCol; col < cellCol ; col++) {
if(getPath().contains(new int[] {cellRow, col})) {
return true;
}
}
return false;
}
private boolean isPathCellOnRight(int cellRow, int cellCol) {
for ( int col = cellCol; col <= maxPathCol ; col++) {
if(getPath().contains(new int[] {cellRow, col})) {
return true;
}
}
return false;
}
private boolean isPathCellOnTop(int cellRow, int cellCol) {
for ( int row =minPathRow; row < cellRow ; row++) {
if(getPath().contains(new int[] {row, cellCol})) {
return true;
}
}
return false;
}
private boolean isPathCellOnBottom(int cellRow, int cellCol) {
for ( int row = cellRow; row <= maxPathRow; row++) {
if(getPath().contains(new int[] {row, cellCol})) {
return true;
}
}
return false;
}
}
关于java - 如果形成路径的元素被包围,则该元素无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44093010/
我正在阅读 deduction guides在 C++17 中。假设我们有以下示例: template struct Custom { }; template struct Person {
我在我的 xamarin 表单项目中使用选项卡式页面。我正在尝试在 Android 的 MyTabsRenderer 类中使用 OnTabReselected 事件。但不会调用 OnTabSelect
我对 NSPredicate 有疑问。想不出一种写法,也找不到类似的东西。我有这个谓词: [NSPredicate predicateWithFormat:@"followedBy.username
我的模态中有一个小表单,如下所示: Name
我正在尝试制作用于表单验证的 jquery 插件(用于学习)。在此表单中,我无法获取类名称为“required”的所有表单字段。代码如下: (function( $ ) { $.fn.kValidat
在我的 Android 应用中,我从 Google Place API 获取附近餐馆的列表。 但不幸的是,这个列表没有给出餐厅的菜单。 我有 T_RESTAURANT 和 T_MENU 表。 假设我在
我正在尝试使用 angular.js 和 devise 设置登录。 这是我的表单 html: Email Password
谁能告诉我如何让生成的文档从表单中提取数据并将其作为标题?我已经查看了 Google Script 文档,但到目前为止我还没有找到任何可以回答我或向我展示类似示例的内容。到目前为止,我在这里找到了相关
当我有这样的表格时: “.”是什么意思?在行动中代表什么? 最佳答案 action 属性告诉表单将表单数据发布到哪里。 . 代表当前目录,所以我会说这是发布到当前目录中的默认文档。 相对路径有几
Mockito 似乎是一个非常漂亮的 Java stub /模拟框架。唯一的问题是我找不到任何关于使用他们的 API 的最佳方式的具体文档。测试中常用的方法包括: doXXX(???) : Stubb
我有 2 份表格。我从一种形式创建并展示了另一种形式。效果很好。但是,当我尝试从创建该表单的表单中关闭或处理该表单时,出现以下异常: Exception : Value Dispose() can
将我的应用程序上传到 TestFlight 时出现以下错误。 但是,我没有看到 missing 的任何位置Xamarin Assets 菜单中的图标。 (76x76、167x167 和 152x152
我的models.py文件看起来像这样 from django.db import models from django.template.defaultfilters import slugify
问题 学习 Xamarin 大学类(class) XAM120 .在将我的 IDial 实现添加到我的 UWP 项目时遇到障碍。出于某种原因,我的项目没有在我的系统上使用 PhoneCallManag
我在应用程序的列表页面上使用了 FloatingActionButton,我还想添加一个 searchBar。但我无法向他们展示该页面。我的代码和屏幕截图已关闭。如何显示搜索栏? FAB Github
实体产品和类别之间存在经典的多对多关系,其中一个产品可能包含在多个类别中。我们想在 UI 中使用带有 UITableViewController 或 UICollectionView 的 NSFetc
html 代码: js代码: function show(){ $.ajax({
我有一个用户列表。现在任何一个名字很长的用户都在搞乱排列/排列。 我认为通过为名称设置大小可以达到目的: .invitee .name{ height: 50px; width: 115px;
我正在使用 Flask 框架和 WTforms 库,我在更改选择字段中每个选项的颜色时遇到了问题,因为它总是显示为黑色而不是红色 我在模板中有下一个表单
Dugen Chen 写了一篇有用的文章,介绍如何将 HTML5 验证中的“required”属性添加到 Django 表单字段。 http://duganchen.ca/elegantly-addi
我是一名优秀的程序员,十分优秀!