Untitled

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
8.1 kB
2
Indexable
Never
#include <iostream>
#include "function.h"
#define MAX_W 123000
using namespace std;

template<class T>
void ChangeSize1D(T*& a, const int oldSize, const int newSize)
{
    //if(newSize<0) throw "New length must be >= 0";
    T* temp = new T[newSize];
    int number = min(oldSize, newSize);
    copy (a, a+number, temp);
    delete [] a;
    a = temp;
}


//STACK


template<class T>
BaseStack<T>::BaseStack()
{
    _top = -1;
    _capacity = 1;
    _stack = new T[_capacity];
}

template<class T>
BaseStack<T>::~BaseStack()
{
    delete [] _stack;
}

template<class T>
inline bool BaseStack<T>::empty()
{
    return size() == 0;
}

template<class T>
inline int BaseStack <T>::size()
{
    return _top+1;
}

template<class T>
inline T& BaseStack<T>::top()
{
    //if(empty()) throw "Stack empty!";
    return _stack[_top];
}

template<class T>
void BaseStack<T>::push (const T& x)
{
    if(_top == _capacity-1)
    {
        ChangeSize1D(_stack, _capacity, 2*_capacity);
        _capacity*=2;
    }
    _stack[ ++_top ] = x;
}

template<class T>
void BaseStack<T>::pop ()
{
    //if(empty()) throw "BaseStack is empty. Cannot delete.";
    _stack[ _top-- ].~T();
    /*if(!empty() && _top == _capacity/2-1 && _capacity>3){
        ChangeSize1D(_stack, _capacity, _capacity/2);
        _capacity/=2;
    }*/
}


//QUEUE


template<class T>
BaseQueue<T>::BaseQueue()
{
    _front = 0;
    _rear = 0;
    _capacity = 1;
    _queue = new T[_capacity];
}

template<class T>
BaseQueue<T>::~BaseQueue()
{
    delete [] _queue;
}

template<class T>
inline bool BaseQueue<T>::empty()
{
    return _front == _rear;
}

template<class T>
inline int BaseQueue<T>::size()
{
    return (_front>_rear)? (_rear+_capacity-_front):(_rear-_front);
}

template<class T>
inline T& BaseQueue<T>::front()
{
    //if(empty()) throw "BaseQueue is empty!";
    return _queue[(_front+1)%_capacity];
}

template<class T>
void BaseQueue<T>::push (const T&x)
{
    if((_rear+1)%_capacity == _front)
    {
        //double queue
        ChangeSize1D(_queue, _capacity, 2*_capacity);
        if(_rear < _front){
            for(int i=_front+1; i<_capacity; i++){
                _queue[i+_capacity] = _queue[i];
                _queue[i].~T();
            }
            _front = (_front+_capacity)%(2*_capacity);
        }

        _capacity *= 2;
    }
    _rear = (_rear+1)%_capacity;
    _queue[_rear] = x;
}

template<class T>
void BaseQueue<T>::pop()
{
    //if(empty()) throw "BaseQueue is empty. Cannot delete.";
    _front = (_front+1)%_capacity;
    _queue[_front].~T();
}


//VARIABLES


BaseStack<pair<int, char>> *enemy;//row, number
BaseStack<pair<int, char>> *result;
BaseQueue<char> SB;
pair<int, int> level;//col, row

//IMPLEMENTATION


void InitialzeStage(int W, int H){
    if(W <= 100000){
        enemy = new BaseStack<pair<int, char>> [10];
        result = new BaseStack<pair<int, char>> [10];
    }else{
        enemy = new BaseStack<pair<int, char>> [MAX_W];
        result = new BaseStack<pair<int, char>> [MAX_W];
    }

    level = {0, 0};
    char c;
    cin.get();
    for(int i=0; i<H; i++){
        for(int j=0; j<W; j++){
            cin.get(c);
            if(c == '1' || c == '2' || c == '3' || c == '4' || c == '5'){
                enemy[j].push({i+1, c});
                if(level.second < i+1)
                    level = {j, i+1};
            }
            cin.get();
        }
    }
}

void ShootNormal(int col, int W){
    if(col>=0 && col<W){
        if(enemy[col].empty() == false){

            char number = enemy[col].top().second;
            enemy[col].pop();

            if(number == '2'){
                SB.push('G');
            }else if(number == '3'){
                SB.push('P');
            }else if(number == '4'){
                SB.push('S');
            }else if(number == '5'){
                int local_level = 0;
                for(int i=col-2; i<col+3; i++){
                    if(i < 0) continue;
                    else if(i >= W) break;

                    if(enemy[i].empty() == false)
                        if(local_level < enemy[i].top().first)
                            local_level = enemy[i].top().first;
                }

                for(int i=col-2; i<col+3; i++){
                    if(i < 0) continue;
                    else if(i >= W) break;

                    enemy[i].push({local_level+1, '1'});
                    enemy[i].push({local_level+2, '1'});
                    enemy[i].push({local_level+3, '1'});

                    if(level.second < local_level+3)
                        level = {i, local_level+3};
                }

            }

            if(level.first == col && number != '5'){
                level = {0, 0};
                for(int i=0; i<W; i++){
                if(enemy[i].empty() == false)
                    if(level.second < enemy[i].top().first)
                        level = {i, enemy[i].top().first};
                }
            }
            //cout<<endl<<"="<<level<<"="<<endl;
        }
    }
}

void ShootSpecial(int col, int W){
    if(SB.empty() == false){
        char bullet = SB.front();
        SB.pop();
        if(bullet == 'G'){
            for(int i=col-2; i<col+3; i++){
                if(i < 0) continue;
                else if(i >= W) break;
                ShootNormal(i, W);
            }
        }else if(bullet == 'P'){
            ShootNormal(col, W);
            ShootNormal(col, W);
            ShootNormal(col, W);
        }else if(bullet == 'S'){
            char head_number = 0;
            if(enemy[col].empty() == false){
                head_number = enemy[col].top().second;
                ShootNormal(col, W);
            }else return;

            while(enemy[col].empty() == false){
                if(head_number == enemy[col].top().second)
                    ShootNormal(col, W);
                else
                    break;
            }
        }
    }
}

void FrontRow(int W){
    cout << "FRONT_ROW, LEVEL:" << level.second << endl;
    if(level.second != 0){
        for(int i=0; i<W; i++){
            if(i>0) cout << ' ';
            if(enemy[i].empty() == false)
                if(enemy[i].top().first == level.second)
                    cout << enemy[i].top().second;
                else
                    cout << '_';
            else
                cout << '_';
        }
        cout << endl;
    }

}

void ShowResult(int W){
    cout << "END_RESULT:" << endl;
    if(level.second != 0){
        for(int i=0; i<W; i++){
            while(enemy[i].empty() == false){
                result[i].push(enemy[i].top());
                enemy[i].pop();
            }
        }
        for(int i=0; i<level.second; i++){
            for(int j=0; j<W; j++){
                if(j>0) cout << ' ';
                if(result[j].empty()) cout << '_';
                else{
                    if(result[j].top().first == i+1){
                        cout << result[j].top().second;
                        result[j].pop();
                    }else cout << '_';

                }
            }
            cout << endl;
        }
    }
}

void deleteStage(){
/*
    for(int i=0; i<MAX_W; i++)
        if(enemy[i].empty() == false)
            enemy[i].~BaseStack();
    for(int i=0; i<MAX_W; i++)
        if(enemy[i].empty() == false)
            result[i].~BaseStack();
    if(SB.empty() == false)
        SB.~BaseQueue();
*/
/*
    while(SB.empty() == false)
        SB.pop();
*/
}

/*
BaseQueue<int> QQ;
void test(){
    for(int i=0; i<50; i++){
        QQ.push(i);
    }
    for(int i=0; i<30; i++){
        cout << QQ.front() << endl;
        QQ.pop();
    }
    for(int i=0; i<50; i++){
        QQ.push(i);
    }
    for(int i=0; i<30; i++){
        cout << QQ.front() << endl;
        QQ.pop();
    }
}*/