| 赞 | 3 |
| VIP | |
| 好人卡 | |
| 积分 | 10 |
| 经验 | |
| 最后登录 | 2026-7-17 |
| 在线时间 | 1391 小时 |
寒
- 梦石
- 0
- 星屑
- 1049
- 在线时间
- 1391 小时
- 注册时间
- 2010-8-9
- 回帖
- 3301
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 寒冷魔王 于 2015-1-31 02:07 编辑
经过多天的书写与调试,我终于将C++的SRPG on Map弄出来了!
首先经过三天重写Ruby的这段代码,然后今天费了一天功夫,终于将C++的那份也给搞定了!(= =不对,今天是31号,已经1点了)
Ruby的重构代码效率是原版本的6~7倍,已经满足正常需求。
而C++的代码测试状态非常好,Ruby代码需要5s,C++刷一下就搞定了!
经过这么些天努力,看到终于成功,心里抑制不住地激动!!
现在只是控制台版本,然后把它做成dll,然后就可以直接调用了!!
SRPG系统最难的地方已经被攻克了!
这两段代码,Ruby昨天又完善一下,C++的是刚出炉的,还热乎呢!
我已经不想说什么了
发布代码:[fold=C++]
[pre lang="Cpp" line="1"]/////////////////////////////////////////////////////////////////////////
// Name: SMCC
// Author: Chill
// Version: 1.0.0.0 BETA
// Date: 01/26/2015 to 01/30/2015
// Direction: SRPG on Map of C++ by Chill.
/////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstring>
using std::cout;
using std::endl;
using std::max;
using std::min;
#define DEBUG
namespace SRPG
{
// System.h
class Clock
{
public:
Clock() : c(clock()) {}
void show() { cout << "The Time is " << clock() - c << "." << endl; }
private:
int c;
};
enum MapData { bland, self, party, enemy, barrier };
enum Direction { wait, up, down, left, right };
struct Data
{
int pass;
int put;
} data[] = {
{ 0, 0 }, // Bland
{ 0, 0 }, // Self
{ 0, 1 }, // Party
{ 1, 1 }, // Enemy
{ 1, 1 }, // Barrier
};
inline int getSize(int move) { return 4 * move + !move; }
inline int getSizes(int moves) { return 2 * (1 + moves) * moves + 1; }
#define ln ;cout<<endl;
inline void putError(bool judge, const char*str)
{
#ifdef DEBUG
if (judge)
{
cout << str << endl;
exit(1);
}
#endif
}
inline void putError(int a, int b, const char*str)
{
#ifdef DEBUG
if (!(a<b))
{
cout << "Error: Arrays in Class " << str << " is Out." << endl;
exit(1);
}
#endif
}
}
namespace SRPG
{
// Map.h
class Map
{
public:
Map(int x = 10, int y = 10) : x(x), y(y), data(new int[x*y]()) {}
Map(const Map &map) : x(map.x), y(map.y), data(new int[x*y]) { for (int i = 0; i < x*y; ++i) data = map.data; }
~Map() { delete[] data; }
const int x, y;
int get(int tx, int ty)const;
void set(int tx, int ty, int e);
void print(int size = 10)const;
private:
int *data = nullptr;
int *map(int tx, int ty)const { return data + tx*this->y + ty; }
bool judgeOut(int tx, int ty)const { return tx >= x || ty >= y || tx < 0 || ty < 0; }
void judgeError(int tx, int ty)const;
};
// Map.cpp
inline void Map::judgeError(int tx, int ty)const
{
#ifdef DEBUG
if (judgeOut(tx, ty))
{
cout << "Arrays in Map ("
<< tx << "," << ty
<< ") is Error." << endl;
exit(1);
}
#endif
}
inline int Map::get(int tx, int ty)const
{
if (judgeOut(tx, ty)) return barrier;
return *map(tx, ty);
}
inline void Map::set(int tx, int ty, int e)
{
judgeError(tx, ty);
*map(tx, ty) = e;
}
void Map::print(int size)const
{
int x = this->x, y = this->y;
x = min(x, size);
y = min(y, size);
for (int ty = 0; ty<y; ty++, cout << endl)
for (int tx = 0; tx<x; tx++)
cout << *map(tx, ty) << " ";
}
}
namespace SRPG
{
// Points.h
class Points
{
public:
Points(int sizes) : sizes(sizes), data(new int[sizes * 2]), temp(data) {}
~Points() { delete[] data; }
void push(int x, int y) { *temp++ = x; *temp++ = y; length++; }
bool include(int x, int y)const;
void print()const;
int getLength()const { return length; }
private:
const int sizes;
int length = 0;
int *data = nullptr;
int *temp = nullptr;
};
// Points.cpp
bool Points::include(int x, int y)const
{
for (int *t = temp - 1; t >= data; t-=2)
if (*t == y && *(t-1) == x)
return true;
return false;
}
void Points::print()const
{
cout << "[";
for (int *ptr = data; ptr < temp - 2; ptr += 2)
cout << "[" << *ptr << ", " << *(ptr + 1) << "], ";
cout << "[" << *(temp - 2) << ", " << *(temp - 1) << "]";
cout << "]" << endl;
}
}
namespace SRPG
{
namespace InRoutes
{
class route
{
class way
{
public:
way() : length(0) {}
way(const way &way) : length(way.length), data(new int[way.length]()) { copyIn(way.data); }
~way() { delete[] data; }
const int length;
way operator+(int e)const { way w(length + 1); copyOut(w.data); *(w.data + length) = e; return w; }
void print()const;
void println()const { print()ln; }
private:
way(int length) : length(length) { if (length) data = new int[length]; }
int *data = nullptr;
void copyIn(int *dat) { for (int *ptr = data; ptr < data + length; *ptr++ = *dat++); }
void copyOut(int *dat)const { for (int *ptr = data; ptr < data + length; *dat++ = *ptr++); }
};
public:
route(int x = 0, int y = 0, bool put = true) : x(x), y(y), ways(), put(put) {}
route(int x, int y, bool put, way way) : x(x), y(y), ways(way), put(put) {}
route(int x, int y, bool put, const route &route, int e) : x(x), y(y), ways(route.ways + e), put(put) {}
const int x, y;
const way ways;
const bool put = true;
void print()const;
void println()const { print()ln; }
};
void route::way::print()const
{
if (!length)
{
cout << "[]";
return;
}
cout << "[";
for (int*ptr = data; ptr < data + length - 1; ptr++)
cout << *ptr << ",";
cout << *(data + length - 1) << "]";
}
void route::print()const
{
cout << "[[" << x << "," << y << "],";
ways.print();
cout << "," << (put ? "true" : "false") << "]";
}
}
namespace InRoutes
{
class routes
{
public:
routes() : uninit(true) {}
routes(int move) : size(getSize(move)), data(new route*[size]) {}
~routes() { if (uninit) return; for (int i = 0; i < length; ++i) delete data; delete[] data; }
void initialize(int move) { if (uninit) { uninit = false; size = getSize(move); data = new route*[size]; } }
int getLength()const { return length; }
void push(const route &r) { putError(length, size, "routes"); data[length++] = new route(r); }
route *operator[](int i)const { putError(i, length, "routes"); return data; }
route *at(int i)const { return (*this); }
void print()const;
void println()const { print()ln; }
private:
int size = 0;
route **data = nullptr;
int length = 0;
bool uninit = false;
};
void routes::print()const
{
cout << "[";
if (length == 0) { cout << "]"; return; }
for (int i = 0; i < length - 1; ++i)
{
data->print();
cout << ",";
}
data[length - 1]->print();
cout << "]";
}
}
}
namespace SRPG
{
class Routes
{
public:
Routes(int moves) : length(moves), data(new InRoutes::routes[moves + 1]) { for (int i = 0; i <= moves; ++i) data.initialize(i); }
~Routes() { delete[] data; }
InRoutes::routes *operator[](int move) { putError(move, length + 1, "Routes"); return data + move; }
InRoutes::routes *at(int move) { return (*this)[move]; }
InRoutes::route *at(int move, int i) { return (*(*this)[move]); }
const int length;
void print();
void println() { print()ln; }
private:
InRoutes::routes *data = nullptr;
};
void Routes::print()
{
for (int i = 0; i <= length; ++i)
data.println();
}
}
namespace SRPG
{
// Route.h
class Route
{
public:
Route(Map map, int x, int y, int moves = 0) : map(map), pX(x), pY(y), moves(moves), points(getSizes(moves)), routes(moves){}
Points *getPoints() { return &points; }
Routes *getRoutes() { return &routes; }
void search() { fsearch(); nsearchs(moves); }
private:
Map map;
int pX, pY;
int moves;
Points points;
Routes routes;
void fsearch();
void nsearch(int move);
void nsearchs(int moves){ for (int i = 1; i <= moves; ++i) nsearch(i); }
void dirMove(int direction, int &x, int &y);
bool pass(int x, int y) { return data[map.get(x, y)].pass==0; }
bool put(int x, int y) { return data[map.get(x, y)].put==0; }
};
// Route.cpp
void Route::fsearch()
{
// Create Refence
InRoutes::routes *routes = this->routes[0];
// Push Data
routes->push(SRPG::InRoutes::route(pX, pY, true));
points.push(pX, pY);
}
void Route::nsearch(int move)
{
// Create Refence
InRoutes::routes *routes = this->routes[move];
InRoutes::routes *rerous = this->routes[move - 1];
// Push Data
for (int i = 0; i < rerous->getLength(); ++i)
{
//rerous->at(i)->println();
InRoutes::route *route = rerous->at(i);
int x = route->x;
int y = route->y;
for (int d = 1; d <= 4; ++d)
{
int tx = x, ty = y;
dirMove(d, tx, ty);
if (points.include(tx, ty)) continue;
if (pass(tx, ty))
{
routes->push(InRoutes::route(tx, ty, put(tx, ty), *route, d));
points.push(tx, ty);
}
}
}
}
void Route::dirMove(int direction, int &x, int &y)
{
switch (direction)
{
case up: y--; break;
case down: y++; break;
case left: x--; break;
case right: x++; break;
}
}
}
// Main.cpp
using namespace SRPG;
bool equal(const char*str, const char*s)
{
for (; *str; ++str, ++s)
if (*str != *s) return false;
return *str == *s;
}
int main(int argv, char*args[])
{
Map map(10,10);
map.set(5, 5, 1);
map.set(4, 5, 3);
map.set(3, 7, 3);
map.set(5, 6, 3);
map.set(4, 7, 4);
map.print();
Route r(map, 5, 5, 10);
Clock c;
r.search();
r.getPoints()->print()ln;
cout << r.getPoints()->getLength() << endl;
if (argv>1 && equal(args[1], "-t"))
c.show();
return 0;
}
[/pre][/fold]
如果用GCC编译的话,请选-std=c++11
[fold=Ruby][pre lang="ruby" line="1"]#===================================================================================
# SMRC.rb
# Author : Chill
# Version : 3.0.0.0 BETA
# Date : 2015-01-27 to 2015-01-29
# Description: SRPG on Map of Ruby by Chill.
#===================================================================================
module Chill
# Point Array
Point = Array.clone
class Point
def include?(point)
self.reverse_each { |p| return true if p[0]==point[0] && p[1]==point[1] }
return false
end
end
# Method
def max(a,b); return (a>b) ? a : b; end
def min(a,b); return (a<b) ? a : b; end
def putError(str); puts(str); exit; end
def reader(symbol); eval(symbol.to_s); end
# Self Method
def self.test(&block)
t = Time.new
block.call
return Time.new - t
end
end
module SRPG
class Map
include Chill
# Reader
attr_reader :x, :y
# Initialize
def initialize(x = 10, y = 10)
@x,@y = x,y
@map = Array.new(x) { Array.new(y,0) }
end
# Data
def judgeOut(x, y)
return x>=@x || y>=@y || x<0 || y<0
end
def judgeError(x, y)
putError("Error: Point in Map (#{x},#{y}) is Out.") if judgeOut(x,y)
end
def get(x, y)
return if judgeOut(x,y); return @map[x][y]
end
def set(x, y, e)
judgeError(x,y); @map[x][y] = e
end
# Method
def prints(maxSize = 10)
x, y = min(maxSize,@x), min(maxSize,@y)
y.times { |y| x.times { |x| print @map[x][y]," " }; print "\n" }
end
def clone
map = Map.new(@x,@y)
dat = map.reader(:@map)
@map.each_index { |i| dat = @map.clone }
return map
end
def include?(e)
@map.each { |map| return true if map.include?(e) }
return false
end
def search(e)
@x.times { |x| @y.times { |y| return [x,y] if @map[x][y] == e } }
return
end
def number(e)
num = 0
@map.each { |map| map.each { |m| num+=1 if m==e } }
return num
end
def transform
@map.each { |m| m.each_index { |i| m = Map.transform(m) } }
return self
end
end
class Map
class Data
def initialize(pass = 0, put = 0)
@pass, @put = pass, put
end
def pass?; return @pass==0; end
def put?; return @put==0; end
end
@@data = {
0 => Data.new(0,0), # 0: Bland
1 => Data.new(0,0), # 1: Self
2 => Data.new(0,1), # 2: Party
3 => Data.new(1,1), # 3: Enemy
4 => Data.new(1,1) # 4: Barrier
}
def self.property(id)
return @@data[4] unless (0..4).include?(id)
return @@data[id]
end
def self.transform(symbol)
case symbol
when 1; 3
when 2; 3
when 3; 2
else; symbol
end
end
end
class Route
include Chill
MaxMoves = 500
# Reader
attr_reader :routes,:points
# Initialize
def initialize(map, moves = nil, position = nil)
@map = map
@position = position.nil? ? map.search(1) : position.clone
@position ||= [0,0]
@map.judgeError(*@position)
@moves = moves if !moves.nil?
end
# Data
def setPosition(x, y)
@map.judgeError(x,y)
@position = [x,y]
end
# Search
def search(moves = 0)
# Record Moves
@moves ||= moves
putError("We Don't Have a Real Value of Moves.") if @moves < 0
@moves = min(MaxMoves,max(moves,@moves))
# Create Arrays
@routes = Array.new(@moves+1) { Array.new }
@points = Point.new
# Start Search
fsearch
nsearchs(@moves)
end
def fsearch
# Create Refence
routes = @routes[0]
# Push Data
routes.push [@position.clone,Array.new,put?(*@position)]
@points.push @position.clone
end
def nsearch(move)
# Create Refence
routes = @routes[move]
# Push Data
@routes[move-1].each do |data|
1.upto(4) do |d|
point = dirMove(d,data[0])
next if @points.include?(point)
if (pass?(*point))
routes.push [point,data[1]+[d],put?(*point)]
@points.push point
end
end
end
end
def nsearchs(a, b = nil)
a,b = 1,a if b.nil?
a.upto(b) { |m| nsearch(m); break if @routes[m].empty? }
end
# Search Method
def dirMove(direction, point)
x,y = point
case direction
when 0; [x, y]
when 1; [x, y-1]
when 2; [x, y+1]
when 3; [x-1, y]
when 4; [x+1, y]
end
end
def pass?(x, y)
return Map.property(@map.get(x,y)).pass?
end
def put?(x, y)
return Map.property(@map.get(x,y)).put?
end
end
class Data
include Chill
# Reader
attr_reader :data
# Initialize
def initialize(data)
@data = data
end
# Set Data
def setMap(args, e)
if args.first.is_a?(Array)
args.each { |args| @data.set(*args,e) }
else
@data.set(*args,e)
end
return self;
end
def setMaps(args)
args.each { |args| setMap(args.first(args.size-1),args.last) }
return self
end
def setPosition(*position)
case @data
when Map
@data.set(*position,1)
when Route
@data.setPosition(*position)
end
return self
end
# Set Map Element
def setSelf(point); @data.set(*point,1); end
def setParty(point); @data.set(*point,2); end
def setEnemy(point); @data.set(*point,3); end
def setBarrier(point); @data.set(*point,4); end
# Get Data
def getSearch(moves = nil)
return @search ||= @data.search(moves)
end
def getRouteData(move = nil)
return move.nil? ? @data.routes : @data.routes[move]
end
def getRoute(x, y)
@data.routes.each { |rs| rs.each { |r| return r if r[0][0]==x && r[0][1]==y } }
return
end
end
end
module SRPG
# TEST
map = Map.new(100,100)
Data.new(map).setMaps([[[50,50],1],[[4,5],[3,7],[5,6],3],[[4,7],4]])
route = Route.new(map,100)
time = Chill.test{ route.search }
map.prints
p route.points.size
#p Data.new(route).getRoute(0,0)
p time
end
[/pre][/fold]
注:这是SRPG地图上关于移动范围生成的代码,并不是寻路算法。但也可以在扩大范围的情况下作为寻路使用。(虽然我当初刚写完Ruby的时候就打算当作寻路来用= =)
虽然我构建这两段代码只用了几天功夫,但是当时开发优化这个算法时费了我近三个月时间。所以还是挺麻烦的。
不得不说一下,虽然我学了C++好几个周,但是也就是菜鸟水平{:5_159:} 不要太过打击我,但是有什么建议希望尽量提。
大触围观:@RyanBern @taroxd |
评分
-
查看全部评分
|