查看: 3667|回复: 4

[随意闲聊] 【测试版代码发布】太激动了!!终于把代码搞定了!!

[复制链接]

寒

梦石
0
星屑
1049
在线时间
1391 小时
注册时间
2010-8-9
回帖
3301
发表于 2015-1-31 01:23:43 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 寒冷魔王 于 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   

评分

参与人数 5星屑 +400 收起 理由
月华风 + 205 吊
玛丽猫 + 120 精品文章
永恒の未知数 + 6 我竟然能看懂一点......
三途亚梦 + 66 总之塞个糖
龙和许也 + 3 好像很历害的樣子~

查看全部评分

梦石
0
星屑
2826
在线时间
2634 小时
注册时间
2013-1-16
回帖
5453

贵宾

发表于 2015-1-31 01:55:52 | 显示全部楼层
貌似是寻路?
个人认为SRPG更精髓的地方是移动范围的生成

点评

↓你说对了~  发表于 2015-1-31 11:18
先生成再寻路  发表于 2015-1-31 11:09
我还是喜欢SRPG,一直梦想着能做SRPG的游戏  发表于 2015-1-31 02:45
感觉那样占内存  发表于 2015-1-31 02:42
先做RPG吧= =  发表于 2015-1-31 02:42
(Created by @喵kano)


施工现场:hotege.github.io
回复

使用道具 举报

寒

梦石
0
星屑
1049
在线时间
1391 小时
注册时间
2010-8-9
回帖
3301
 楼主| 发表于 2015-1-31 02:43:24 | 显示全部楼层
本帖最后由 寒冷魔王 于 2015-1-31 02:46 编辑
myownroc 发表于 2015-1-31 01:55
貌似是寻路?
个人认为SRPG更精髓的地方是移动范围的生成

基本的单元{空地=0,自己=1,友军=2,敌人=3,普通障碍=4,减速障碍=5}
  1. 角色1:
  2. 0 0 0 0 0
  3. 0 4 0 2 0
  4. 0 0 1 0 0
  5. 0 5 0 3 0
  6. 0 0 0 0 0
  7. 角色2:
  8. 0 0 0 0 0
  9. 0 4 0 1 0
  10. 0 0 2 0 0
  11. 0 0 0 3 0
  12. 0 0 0 0 0
复制代码

点评

寒冷魔王-3  发表于 2015-1-31 19:04
myownroc +1  发表于 2015-1-31 18:30
taroxd +1  发表于 2015-1-31 18:01
chd菊苣的智商不是你能理解的  发表于 2015-1-31 17:59
需要啊···比如地形什么的,在同一个格子上不停种植物消耗增加  发表于 2015-1-31 17:51
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2015-1-31 08:31:54 | 显示全部楼层
本帖最后由 taroxd 于 2015-1-31 11:02 编辑

reader 不就是 instance_variable_get 么- - 连 minmax 都要你优化了,这个还用 eval ?

你上次问(是不是你来着……)有没有连续的数据结构。没记错的话,RGSS 的 Table 就是一种的说~

反正算法这种东西不仔细看是看不懂的(我承认我懒得去看,因为不是很感兴趣),我就不吐槽了。楼主加油吧。
说起来你们都写C++了还用RM干啥= =

点评

对了,几个月前提到Ruby的继承关系时说到Perl,松本行弘老人家说他大学时开发Ruby深受Perl影响,但是只是样子像,里面很不同。  发表于 2015-1-31 12:32
嗯,看来是这样,,Fortran在某些方面跟C比快的多得多  发表于 2015-1-31 12:28
“C 比汇编能慢多少”这句是针对“Fortran 和 C 不在一个等级上”说的。连汇编和 C 都没差一个等级吧  发表于 2015-1-31 12:26
怎么可能差一个等级……C 比汇编能慢多少……  发表于 2015-1-31 12:24
Java速度接近C但是有两倍之差,C接近汇编,估计也是差了许多  发表于 2015-1-31 12:24
回复

使用道具 举报

刷下限の口苗君

梦石
0
星屑
51
在线时间
748 小时
注册时间
2010-11-5
回帖
1744
发表于 2015-1-31 11:16:54 | 显示全部楼层
比赛前就被刷下去的信奥选手的表示…我看不懂
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部