PHP像素映射组效率

PHP像素映射组效率,php,mysql,arrays,coordinates,Php,Mysql,Arrays,Coordinates,我目前有一个1600 x 1600的地图存储在MySQL中(2560000条记录)。我正在绘制一个简单的25x25地图,供用户交互。用户可以在此地图上“认领”瓷砖。我希望能够计算给定用户拥有的瓷砖的开放面数量。我可以将其除以拥有的瓷砖总数,以确定任意的效率等级 所有地图坐标仅存储为X/Y值 我正在寻找能够潜在地处理所述X/Y值数组并确定每个所属组可访问的开放面数量的东西。例如 0 = player x x x x x x x 0 x x x x x x x 4 open faces x x x

我目前有一个1600 x 1600的地图存储在MySQL中(2560000条记录)。我正在绘制一个简单的25x25地图,供用户交互。用户可以在此地图上“认领”瓷砖。我希望能够计算给定用户拥有的瓷砖的开放面数量。我可以将其除以拥有的瓷砖总数,以确定任意的效率等级

所有地图坐标仅存储为X/Y值

我正在寻找能够潜在地处理所述X/Y值数组并确定每个所属组可访问的开放面数量的东西。例如

0 = player
x x x x x
x x 0 x x
x x x x x
4 open faces

x x x x x 
x x 0 x x 
x x 0 x x 
x x x x x 
6 open faces

x x x x x 
x x x 0 x
x x 0 x x
x x x x x 
8 open faces
现在我正在做一些低效的数组循环来计算这个。我有一个简单的计数器,然后我循环遍历所有值的数组,在X和Y的每个方向上寻找值+-1以减少计数。每个循环根据找到的数量向总计数器添加0-4。这种方法的固有问题是,随着群体的增长,计算出来的时间会越来越长。因为一个团队可能消耗20000分,这是一个相当大的负担


非常感谢您的帮助。

一种方法是创建一个
类。例如:

class Point {
    public $x;
    public $y;

    public function __construct($x, $y){
        $this->x = $x;
        $this->y = $y;
    }

    public function getNeighbors(){
        // TODO: What if we are at the edge of the board?

        return array(
            new Point($x+1, $y+1),
            new Point($x+1, $y-1),
            new Point($x-1, $y+1),
            new Point($x-1, $y-1),
        );
    }
}
为用户占用的每个点从该类创建实例:

// Generate array of Points from database
$user_points = array(new Point(134, 245), new Point(146, 456));
通过迭代生成所有邻居:

// Get a flat array of neighbor Points
$neighbors = array_merge(array_map(function($point){
    return $point->getNeighbors();
}, $user_points));

// TOOD: Remove Points that are equal to values in $user_points
然后,最后,提交“邻居”点的
COUNT
查询,以确定其他用户占用了多少点,并从总数中删除这些点

(注意:我添加了需要做更多工作的TODO。)


这种方法的固有问题是,随着群体的增长,计算出来的时间会越来越长


您应该考虑使用内存中的键值存储,比如。但是,是的,查找时间(对于占用的块),在时间复杂度上,与条目的数量呈线性关系。

这是我提出的确定地理效率的简单代码的最后一块。有些东西的名字已经改了P

我在运行通知,所有的东西都是ajax,所以我决定在多维上使用单个isset检查,而不是其他检查

$sql = 'SELECT map_x, map_y FROM Map WHERE person_id = :person_id';
$query = $DB->prepare($sql);
$query->execute(array(':nation_id' => $this->person_id));
$counter = 0;
$coords = array();
while($row = $query->fetch())
{
    ++$counter;
    $coords[$row['map_x']][$row['map_y']] = 1;
}
$faces = 0;
foreach($coords as $x => $batch)
{
    foreach($batch as $y => $junk)
    {
        $hits = 4;
        if(isset($coords[$x + 1][$y]))
        {
            --$hits;
        }
        if(isset($coords[$x - 1][$y]))
        {
            --$hits;
        }
        if(isset($coords[$x][$y - 1]))
        {
            --$hits;
        }
        if(isset($coords[$x][$y + 1]))
        {
            --$hits;
        }
        $faces += $hits;
    }
}

我希望你的第三个例子是6张开放的脸,因为其中2张是“共享的”,这就是为什么这是一个独特的问题。这与你通常所想的不同。在剔除点时,我如何确定两个瓷砖是否共享同一个开放瓷砖,以将其计算为多个面?我会尝试一下,看看能不能加快速度。明天我将发布我当前的解决方案。谢谢你的主意,雅各布!我知道不用hits变量,我可以轻松地增加faces变量,但是在ifs之后添加了一些额外的特性。