PHP 像素映射组效率


PHP Pixel Map Group Efficiency

>我目前有一个存储在MySQL中的1600 x 1600的地图(2,560,000条记录)。 我正在渲染一个简单的 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 添加到总计数器中。 这种方法的固有问题是,随着群体的增长,计算出来所需的时间会越来越长。 由于一组人有可能消耗20,000点,因此这是一个相当大的负担。

任何帮助将不胜感激。

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

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查询,以确定其他用户占用了多少点,并从总数中删除这些点。

(注意:我添加了待办事项,其中需要完成更多工作。


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

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

这是我想出的最后一块简单代码,用于确定地理效率。 一些事物的名称已更改。: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;
    }
}